Изменение таблицы MySQL (Percona 5.7) не выполняется из-за повторяющихся ошибок ввода - PullRequest
0 голосов
/ 21 декабря 2018

Мы обновили MySQL (Percona) с 5.6 до 5.7, и нам сказали, что некоторые таблицы необходимо изменить / отремонтировать, потому что поле datetime теперь другое.Изменение таблицы завершается неудачно с ошибкой повторяющегося ввода, несмотря на наличие первичного ключа в обоих полях, device_id и ts, и все данные выглядят нормально (без дубликатов).Насколько я знаю, первичный ключ также должен быть уникальным.

Мы попытались выбрать повторяющиеся записи по условиям 'device_id' и 'ts' в части WHERE, и он находит только 1 экземпляр записи.Когда мы пытаемся выбрать только по полю ts, он находит 2 экземпляра одной и той же записи.Как это возможно?Что это за дубликаты?Ключи повреждены?Есть ли другой способ, кроме как создать новую таблицу и передать туда все данные с помощью INSERT IGNORE?

Редактировать: ошибка следующая:

ERROR 1062 (23000): Duplicate entry '486-2014-10-26 02:39:33' for key 'PRIMARY'

Редактировать 2: Структура таблицыследующим образом (device_id, ts и 32 датчика):

CREATE TABLE IF NOT EXISTS `sensor_log` (
    `device_id` int(11) NOT NULL,
    `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `D1` smallint(6) DEFAULT NULL,
    `D2` smallint(6) DEFAULT NULL,
    ...
    `D30` smallint(6) DEFAULT NULL,
    `D31` smallint(6) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
/*!50100 PARTITION BY RANGE ( UNIX_TIMESTAMP(ts))
(PARTITION p_sl_2013 VALUES LESS THAN (1388530800) ENGINE = InnoDB,
    PARTITION p_sl_2014 VALUES LESS THAN (1420066800) ENGINE = InnoDB,
    PARTITION p_sl_2015 VALUES LESS THAN (1451602800) ENGINE = InnoDB,
    PARTITION p_sl_2016 VALUES LESS THAN (1483225200) ENGINE = InnoDB,
    PARTITION p_sl_2017_q1 VALUES LESS THAN (1490997600) ENGINE = InnoDB,
    PARTITION p_sl_2017_q2 VALUES LESS THAN (1498860000) ENGINE = InnoDB,
    PARTITION p_sl_2017_q3 VALUES LESS THAN (1506808800) ENGINE = InnoDB,
    PARTITION p_sl_2017_q4 VALUES LESS THAN (1514761200) ENGINE = InnoDB,
    PARTITION p_sl_2018_q1 VALUES LESS THAN (1522533600) ENGINE = InnoDB,
    PARTITION p_sl_2018_q2 VALUES LESS THAN (1530396000) ENGINE = InnoDB,
    PARTITION p_sl_2018_q3 VALUES LESS THAN (1538344800) ENGINE = InnoDB,
    PARTITION p_sl_2018_q4 VALUES LESS THAN (1546297200) ENGINE = InnoDB,
    PARTITION p_sl_2019_q1 VALUES LESS THAN (1551394800) ENGINE = InnoDB,
    PARTITION p_sl_2019_q2 VALUES LESS THAN (1556661600) ENGINE = InnoDB,
    PARTITION p_sl_2019_q3 VALUES LESS THAN (1561932000) ENGINE = InnoDB,
    PARTITION p_sl_2019_q4 VALUES LESS THAN (1567288800) ENGINE = InnoDB,
    PARTITION p_sl_2019_q5 VALUES LESS THAN (1572562800) ENGINE = InnoDB,
    PARTITION p_sl_2019_q6 VALUES LESS THAN (1577833200) ENGINE = InnoDB,
    PARTITION p_sl_X VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;

--
-- Indexes for table `sensor_log`
--
ALTER TABLE `sensor_log`
ADD PRIMARY KEY (`device_id`,`ts`);

1 Ответ

0 голосов
/ 21 декабря 2018

Когда ошибка выглядит примерно так:

ERROR 1022 (23000): Can't write; duplicate key in table '#sql-6b04_a0'

, вы, вероятно, пытаетесь создать внешний ключ дважды с тем же именем.Или что-то типа того.Проверьте свои внешние ключи.

Если вы хотите принудительно обновить таблицу в новом формате, вам не нужно вносить какие-либо изменения в таблицу.Просто сделайте

ALTER TABLE foo FORCE;

РЕДАКТИРОВАТЬ:

У вас есть дубликаты записей в вашей таблице.Ваш первичный ключ охватывает два столбца.Ищите эти дубликаты с помощью

SELECT device_id, ts, COUNT(*)
FROM your_table
GROUP BY device_id, ts
HAVING COUNT(*) > 1

. Затем вам придется очистить таблицу, убедившись, что присутствует только одна запись для каждой комбинации device_id и ts.

...