У нас есть таблица в Cassandra версии 3.11.7. После миграции трех узлов в другую зону доступности я столкнулся с проблемой, когда я не могу получить данные по первичному ключу, несмотря на то, что данные были успешно вставлены.
CREATE TABLE m_operational.app_settings (
endpoint_id text PRIMARY KEY,
format text,
settings_json text,
platform text
) WITH bloom_filter_fp_chance = 0.01
AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
AND comment = ''
AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
AND crc_check_chance = 1.0
AND dclocal_read_repair_chance = 0.1
AND default_time_to_live = 0
AND gc_grace_seconds = 864000
AND max_index_interval = 2048
AND memtable_flush_period_in_ms = 0
AND min_index_interval = 128
AND read_repair_chance = 0.0
AND speculative_retry = '99PERCENTILE';
Выберите запрос, который я пытаюсь выполнить:
select * from m_operational.app_settings where endpoint_id='endpoint-i-need';
И я ничего не получаю даже после запроса на вставку:
INSERT INTO m_operational.app_settings (endpoint_id, format, settings_json, platform) VALUES( 'endpoint-i-need', 'free', '{""settings"": ""my-settings""}', 'PC');
попробовал создать рядом аналогичную запись, но с другим ключом - всё заработало:
INSERT INTO m_operational.app_settings (endpoint_id, format, settings_json, platform) VALUES( 'endpoint-i-need1', 'free', '{""settings"": ""my-settings""}', 'PC');
select * from m_operational.app_settings where endpoint_id='endpoint-i-need1';
Данная проблема начала возникать при миграции 3-х нод Cassandra из одной зоны доступности в другую и остается по сей день (В кластере 9 нод).
Миграция осуществлялась следующим образом:
После миграции я выполняю nodetool cleanup
на каждом из узлов, а затем запускаю восстановление с помощью команды nodetool repair --full -pr -j 2
на каждом из узлов. Ничего не изменилось, и выбор по-прежнему не работает. Затем я попытался запустить восстановление конкретной таблицы на всех узлах с помощью nodetool repair --full -pr -j 2 m_operational app_settings
— это тоже не помогло.
Что я могу посмотреть в Кассандре, чтобы понять причину проблемы? или как я могу решить эту проблему?
Добро пожаловать в Stack Overflow! Дружеское напоминание о том, что этот сайт предназначен для получения помощи по проблемам кодирования, алгоритмов или языков программирования, поэтому я проголосовал за перемещение вашего сообщения в DBA Stack Exchange . Для дальнейшего использования вам следует публиковать вопросы по администрированию/операции БД на странице dba.stackexchange.com/questions/ask?tags=cassandra. Ваше здоровье!
Я предполагаю, что кто-то удалил раздел с отметкой времени, установленной в будущем, поэтому дата надгробия будет более поздней, чем любое из заявлений INSERT
, которые вы делаете.
Это было бы легко доказать с помощью небольшого расследования. Сначала необходимо определить реплики, владеющие разделом, с помощью:
$ nodetool getendpoints -- m_operational app_settings <pkey>
Затем для каждой реплики определите SSTables, содержащую раздел, с помощью:
$ nodetool getsstables -- m_operational app_settings <pkey>
Просмотрите содержимое каждой таблицы SSTable, используя sstabledump
, и найдите надгробие, особенно дату/время удаления:
$ sstabledump -k <pkey> /path/to/data/.../...Data.db
ВНИМАНИЕ! sstabledump
— это офлайн-инструмент. Перед использованием утилиты необходимо остановить Cassandra, иначе нормальная работа узла может быть нарушена.
Когда вы идентифицируете таблицы SSTable, содержащие «будущее» надгробие, вам нужно будет переместить его (и соответствующие ему компоненты, такие как *-Statistics.db
, *-Index.db
и т. д.) из каталога данных, поскольку невозможно удалить надгробия путем удаления. время, установленное на будущее. Ваше здоровье!
Да, вы правы, спасибо - так и получилось, нашел запись с удалением в дальнейшем. Но я сомневаюсь в перемещении файлов таблицы ss из каталога data, боюсь, что это может как-то повредить данные в таблице. Знаете, такое может случиться или мне не стоит бояться?
И если это не опасно, то нужно ли это делать сразу на всех узлах, где находятся битые файлы одновременно? или я могу перемещать эти файлы по одному узлу за раз?
Да, это может быть опасно, поскольку может привести к потере данных, поэтому вам придется анализировать данные на каждой реплике. Будем надеяться, что SSTables не все содержат одинаковые разделы. В противном случае вам придется вручную перезагрузить данные, реконструируя операторы INSERT
/UPDATE
/DELETE
из вывода sstabledump
. Ваше здоровье!
Не могли бы вы показать здесь результат работы
DESCRIBE KEYSPACE m_operational;
? Были ли новые узлы добавлены в существующий центр обработки данных/регион или как отдельный центр обработки данных/регион? [Меня это смутилоReconfiguration of services to use new nodes
, поскольку клиенты узнают всю топологию после подключения только к узлам начальной точки контакта]. И, кстати, для ремонта всегда рекомендуется использоватьnodetool repair -pr
по одному узлу за раз на всех узлах кластера (или оставить это таким инструментам, как reaper, чтобы они позаботились об этом автоматически).