從庫show slave status監控的時候發現sql_thread進程已經變成NO,而且爆出了1362錯誤,仔細查看報錯的是一條insert into語句,而且拋出了一個詳細的錯誤,大體的意思就是字段column_1設置了NOT NULL可是沒有插入值而且沒有默認值。而後仔細檢查了一下表結構,具體信息以下mysql
在看到這個報錯的信息的時候,直接google了一下,大部分答案顯示都是因爲sql_mode的緣由所致使的,要想解決這個問題,必須將執行:sql
mysql> set global sql_mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
可是我在slave獲取獲得的sql_mode就是 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
,這個時候我在本身本地執行這個insert 插入語句驗證是否能夠插入成功,發現是能夠插入的。session
這個時候我就想這個是否在主從複製的過程當中,slave在執行這個insert插入的時候sql_mode發生了更改了,這個時候我解析slave的relay log信息獲取獲得 :架構
# at 271 #181019 12:13:00 server id 5403005 end_log_pos 319 CRC32 0x755a7204 GTID [commit=yes] SET @@SESSION.GTID_NEXT= '8e91de47-8f0b-11e8-824c-246e9699bb48:1408667354'/*!*/; # at 319 #181019 12:13:00 server id 5403005 end_log_pos 440 CRC32 0x1add7880 Query thread_id=47560669 exec_time=0 error_code=0 SET TIMESTAMP=1539922380/*!*/; SET @@session.pseudo_thread_id=47560669/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1344274432/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8mb4 *//*!*/; SET @@session.character_set_client=45,@@session.collation_connection=45,@@session.collation_server=45/*!*/; SET @@session.time_zone='SYSTEM'/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; BEGIN /*!*/; # at 440 #181019 12:13:00 server id 5403005 end_log_pos 689 CRC32 0x1537384f Query thread_id=47560669 exec_time=0 error_code=0 use `finance_fixin_product`/*!*/; SET TIMESTAMP=1539922380/*!*/; ..... ..... ..... /*!*/;
能夠很明顯的獲得在上面binlog中有一個 SET @@session.sql_mode=1344274432/!/; 操做,那麼這操做將賦予sql_mode什麼值呢?app
mysql> SET @@session.sql_mode=1344274432; Query OK, 0 rows affected (0.00 sec) mysql> select @@global.sql_mode; +--------------------------------------------+ | @@global.sql_mode | +--------------------------------------------+ | NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | +--------------------------------------------+ 1 row in set (0.00 sec) mysql> select @@sql_mode; +----------------------------------------------------------------+ | @@sql_mode | +----------------------------------------------------------------+ | STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | +----------------------------------------------------------------+ 1 row in set (0.00 sec)
執行操做以後,忽然發現sql_mode多出來一個STRICT_TRANS_TABLES,這個時候大體能夠獲取獲得端倪了,由於在binlog在執行這條SQL的設置了session的sql_mode爲嚴格模式,因此致使在sql_thread重放的時候出現了這個問題。ide
可是這個時候又冒出了一個新的問題,由於線上的表結構和架構和測試環境如出一轍,而且線上運行了這麼久的時間也沒有出現這個問題,帶着這個疑問我再次解析了線上binlog的日誌信息:函數
#181101 10:12:26 server id 5403005 end_log_pos 420 CRC32 0x2fe38b78 Query thread_id=51519927 exec_time=0 error_code=0 SET TIMESTAMP=1541038346/*!*/; SET @@session.pseudo_thread_id=51519927/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1344274432/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8mb4 *//*!*/; SET @@session.character_set_client=45,@@session.collation_connection=45,@@session.collation_server=45/*!*/; SET @@session.time_zone='SYSTEM'/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; BEGIN /*!*/; # at 420 #181101 10:12:26 server id 5403005 end_log_pos 538 CRC32 0xb848f658 Table_map: `finance_fixin_cgb_gateway`.`t_cgb_receive_message` mapped to number 2056756 # at 538 #181101 10:12:26 server id 5403005 end_log_pos 740 CRC32 0x42756468 Write_rows: table id 2056756 flags: STMT_END_F ### INSERT INTO ### SET ### @1=5300431 ### @2='PA0052' ### @3='b0009201811010033433728' ### @4='10.201.5.129' ### @5=2433 ### @6='128' ### @7='0009a201811010143659612590571520' ### @8='000920180907OR23805082566791168' ### @9='0' ### @10='0000' ### @11='0000-操做成功。' ### @12='2018-11-01 10:12:26' ### @13='2018-11-01 10:12:26' # at 740 #181101 10:12:26 server id 5403005 end_log_pos 771 CRC32 0xf5516de4 Xid = 12837058229 COMMIT/*!*/;
對比以後發現,線上的binlog格式是ROW格式,而且經過查看insert語句發如今insert插入的時候沒有默認值會默認設置爲' ',因此slave是不會報錯的。測試
這個時候提出了倆個方案:google
最後和開發溝通以後仍是選擇了第一個方案,修改表結構,主要是binlog格式的修改,必須先要斷開全部的連接,因此綜合考慮直接修改了表結構。日誌
在binlog爲statement的時候解析了發現了一條SET TIMESTAMP=1539922380語句,以前一直認爲在statement格式下面使用時間函數會致使主從數據不一致,如今看到這個SQL,發現並不出現這種狀況。