AssertionError после удаления SSTable вручную из Кассандры

Я вручную удалил несколько SSTables из Кассандры из-за нехватки места. После этого я получаю следующую ошибку каждый раз, когда я выполняю nodetool cfstats KEYSPACE.COLUMNFAMILY, Почему он пытается выяснить SSTable, который я удалил, и выдает AssertionError?

error: /mnt/cassandra2112/data/data/KEYSPACE/COLUMNFAMILY-3ef09530a70811e6ae4f97f9576f9b43/KEYSPACE-COLUMNFAMILY-ka-14-Data.db
    -- StackTrace --
    java.lang.AssertionError: /mnt/cassandra/data/data/KEYSPACE/COLUMNFAMILY-3ef09530a70811e6ae4f97f9576f9b43/KEYSPACE-COLUMNFAMILY-ka-14-Data.db
        at org.apache.cassandra.io.sstable.SSTableReader.getApproximateKeyCount(SSTableReader.java:268)
        at org.apache.cassandra.metrics.ColumnFamilyMetrics$9.value(ColumnFamilyMetrics.java:296)
        at org.apache.cassandra.metrics.ColumnFamilyMetrics$9.value(ColumnFamilyMetrics.java:290)
        at com.yammer.metrics.reporting.JmxReporter$Gauge.getValue(JmxReporter.java:63)
        at sun.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:75)
        at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:279)
        at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:112)
        at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:46)
        at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:237)
        at com.sun.jmx.mbeanserver.PerInterface.getAttribute(PerInterface.java:83)
        at com.sun.jmx.mbeanserver.MBeanSupport.getAttribute(MBeanSupport.java:206)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:647)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678)
        at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1464)
        at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:97)
        at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1328)
        at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1420)
        at javax.management.remote.rmi.RMIConnectionImpl.getAttribute(RMIConnectionImpl.java:657)
        at sun.reflect.GeneratedMethodAccessor8.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
        at sun.rmi.transport.Transport$2.run(Transport.java:202)
        at sun.rmi.transport.Transport$2.run(Transport.java:199)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:198)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:567)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.access$400(TCPTransport.java:619)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:684)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(TCPTransport.java:681)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:681)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)

2 ответа

Тебе этого не сделать.

Cassandra обрабатывает данные в несколько этапов на пути записи, начиная с немедленной регистрации записи и заканчивая записью данных на диск:

  • Регистрация данных в журнале фиксации
  • Запись данных в память
  • Сброс данных из памяти
  • Хранение данных на диске в SSTables

Memtables и SSTables поддерживаются для каждой таблицы. SSTables являются неизменяемыми и не записываются снова после сброса memtable. Следовательно, раздел обычно хранится в нескольких файлах SSTable.

Это означает, что вам нужны SSTables для чтения данных из хранилища.

Для получения дополнительной информации: Как данные записываются на кассандре?

Что если вы поедете к машине вашего брата и снимите одну шину? Тот факт, что он не собирается бегать с ним по шоссе, не означает, что он не заметит, что шина отсутствует.


Короткий ответ

Не удаляйте SSTables вручную.


Длинный ответ

Таблицу Кассандры можно сохранить на диске в несколько таблиц SSTable. Они на самом деле являются вашими данными, будь то живые данные или удаленные данные (да, они все еще являются вашими данными, и с них будет взиматься плата, пока не произойдет уплотнение, и они называются надгробными плитами!)

Вы, вероятно, удалили "живой" SSTable. Единственное, что вы можете удалить без жалоб C*, это снимки. И когда вы это сделаете, вам нужно использовать правильный инструмент.

Если у вас мало места, пришло время добавить один узел в ваш кластер.

Если вы не ожидали, что не хватит места, пришло время вернуться и изменить дизайн вашей модели данных.

НТН.

Другие вопросы по тегам