1. 程式人生 > 其它 >odbc insert中包含中文_ptosc改表過程中的中文亂碼問題

odbc insert中包含中文_ptosc改表過程中的中文亂碼問題

技術標籤:odbc insert中包含中文

4a730e85547d7f94df259a611a0b21f8.png

eca6ab563078e1d664c4d005e965e5d1.gif//

pt-osc改表過程中的中文亂碼問題

//

下午使用pt-osc工具對線上表進行變更的時候,發現了一個問題,在對latin1字符集進行變更的時候,變更完畢之後的表的中文註釋都變成了'?',無法正常顯示了。於是在測試環境上進行了實驗。

mysql>showcreatetablelatin_test1\G
***************************1.row***************************
Table:latin_test1
CreateTable:CREATETABLE`latin_test1`(
`id`int(11)NOTNULL,
`name`varchar(10)DEFAULTNULLCOMMENT'任務名稱',
PRIMARYKEY(`id`),
)ENGINE=InnoDBDEFAULTCHARSET=latin1
1rowinset(0.00sec)

#pt指令
pt-online-schema-change--user=dba_admin--password=xxxxxxxx-h127.0.0.1-P4306--alter"ADDindexidx_name(name)"D=yeyz,t=latin_test1--alter-foreign-keys-method=auto--recursion-method=none--print--charset=latin1--execute

首先建立一張字符集為latin1的表,它包含id和name兩個欄位,然後對這個表的name欄位新增索引,變更的pt指令如上文,其中:

--charset=latin1

當我們變更完成之後,發現變更的新表內容變成:

mysql>showcreatetablelatin_test1\G
***************************1.row***************************
Table:latin_test1
CreateTable:CREATETABLE`latin_test1`(
`id`int(11)NOTNULL,
`name`varchar(10)DEFAULTNULLCOMMENT'????',
PRIMARYKEY(`id`),
KEY`idx_name`(`name`)
)ENGINE=InnoDBDEFAULTCHARSET=latin1
1rowinset(0.00sec)

可以看到,comment的值變成了'????',而不是我們之前的任務名稱。

出現這個情況之後,我重新做了一個測試,在pt工具的指令中,將--charset引數改成了utf8,pt指令如下:

pt-online-schema-change--user=dba_admin--password=xxxxxxx-h127.0.0.1-P4306--alter"modifynamevarchar(10)DEFAULTNULLCOMMENT'任務名稱'"D=yeyz,t=latin_test1--alter-foreign-keys-method=auto--recursion-method=none--print--charset=utf8--execute

執行完成之後,結果如下:

mysql>showcreatetablelatin_test1\G
***************************1.row***************************
Table:latin_test1
CreateTable:CREATETABLE`latin_test1`(
`id`int(11)NOTNULL,
`name`varchar(10)DEFAULTNULLCOMMENT'任務名稱',
PRIMARYKEY(`id`)
)ENGINE=InnoDBDEFAULTCHARSET=latin1
1rowinset(0.00sec)

這個結果中,我們可以看到2點:

1、我們的表latin_test1的字符集仍舊是latin1,而沒有被改成utf8的字符集

2、表中的中文註釋已經可以顯示了。

--charset這個引數在pt-osc這個工具中,指的是使用哪種字符集去連線資料庫,如果使用utf8的話,那麼在連線到資料庫之後,會首先執行set names utf8;它指定了客戶端和伺服器之間傳遞字元的編碼規則為UTF8。如果我們使用latin1這個字符集,則說明pt-osc工具和mysql互動的字符集是latin1,而這個字符集是無法儲存漢字的,所以結果中就出現了????的字眼。

除此之外,今天還專門看了下pt-osc工具建立的三個觸發器的內容,觸發器的內容不是單純的將主庫上的動作原封不動的搬遷到從庫上,它的建立規則如下:

(1)對於DELETE操作,pt工具使用DELETE IGNORE在新表進行刪除,當新有資料時,我們才進行操作,也就是說,當在後續匯入過程中,如果刪除的這個資料還未匯入到新表,那麼我們可以不在新表執行操作,因為在以後的匯入過程中,原表中改行資料已經被刪除,已經沒有資料,那麼這條記錄也就不會匯入到新表中;
(2)對於INSERT操作,所有的INSERT INTO全部轉換為REPLACE INTO,當有新資料插入到原表時,如果觸發器還未把原表資料同步到新表,而這條資料已經被pt工具匯入到新表了,再次insert就會發生報錯,那麼我們就可以利用replace into進行覆蓋,這樣資料也是一致的
(3)對於UPDATE操作,所有的UPDATE也轉換為REPLACE INTO,因為當更新的資料的行還未同步到新表時,新表是不存在這條記錄的,直接update肯定會報錯,那麼我們就只能插入該條資料,如果已經同步到新表了,那麼也可以進行覆蓋插入,所有資料與原表也是一致的;

d8291823a24de9fb01ccae952a94dfea.png 6677dd4d61b5c7437046e45a29c7e136.png有幫助的話還希望點下再看哈