Mysql

MySQL 5.7下日期欄位的奇怪複製失敗

  • July 22, 2021

這個問題昨天突然出現了,我很困惑。我有一個執行 MySQL 5.6 的主 RDS 集群,並且 RDS 很快就會迫使每個人都使用 5.7。我有一個較小的獨立複製從站,我們用於一些繁重的報告查詢。昨天從伺服器移動到 5.7(我認為 RDS 在從伺服器升級時不允許主伺服器升級),複製執行了大約 6 個小時,但最終因為這個 1292 SQL 錯誤而硬停止

Error 'Incorrect date value: '' for column 'delivery_date' at row 1' on query. 
Default database: 'dbname'. Query: 'INSERT shipment SET
                   carrier = "Shipper",
                   bill_number = "1234",
                   tracking_num = "1234",
                   invoice_date = "2021-07-08",
                   fee = "1.00",
                   ship_date = "2021-06-10",
                   delivery_date = NULL,
                   zip_from = "ABCD",
                   zip_to = "",
                   recipient = "||",
                   shipper = "COMPANY",
                   notes = "||||",
                   found = "No"'

這個錯誤沒有意義。該欄位允許 NULL 所以它不應該是一個問題。這是結構

CREATE TABLE `shipment` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `carrier` varchar(45) NOT NULL,
 `bill_number` varchar(45) NOT NULL,
 `tracking_num` varchar(45) NOT NULL,
 `invoice_date` date NOT NULL,
 `fee` decimal(8,2) NOT NULL,
 `ship_date` date DEFAULT NULL,
 `delivery_date` date DEFAULT NULL,
 `recipient` varchar(255) DEFAULT NULL,
 `shipper` varchar(255) DEFAULT NULL,
 `zip_from` varchar(5) DEFAULT NULL,
 `zip_to` varchar(5) DEFAULT NULL,
 `notes` text,
 `found` enum('No','Yes','PO','Invoice','Event','Manual','Fee','Supplies') NOT NULL DEFAULT 'No',
 PRIMARY KEY (`id`),
 UNIQUE KEY `carrier` (`carrier`,`bill_number`,`tracking_num`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

這是sql-mode來自配置

sql-mode="STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

我已經嘗試刪除STRICT_TRANS_TABLES,甚至是那裡的大部分配置(RDS 不會讓您空白該欄位)並且沒有運氣。我們的開發伺服器使用 5.7 已經有一段時間了,並且毫無怨言地接受了查詢(都是 5.7.34)。跳過沒有幫助,因為有幾十條記錄需要像這樣更新,所以它仍然會中斷。

顯然有一個觸發器不在複製伺服器上的實時數據庫中

CREATE DEFINER=root@% TRIGGER invoice_insert 
BEFORE INSERT ON shipment 
FOR EACH ROW BEGIN IF NEW.delivery_date = "" THEN SET NEW.delivery_date = NULL; 
END IF; 
END

在觸發器中,更改

IF NEW.delivery_date = ""

IF NEW.delivery_date < '1971-01-01'

這將擷取空字元串和'1970-01-01' and any timezone variation on that "zero" date. It will fail if it is already NULL`,但這不會改變觸發器的動作。

(將來,請務必在問題中包含任何相關的觸發器。)

引用自:https://dba.stackexchange.com/questions/295961