1 工具原理
pt-online工具主要是為了實現在線修改表結構,避免執行執行造成的鎖表時間太長問題。其運行原理是按執行的SQL命令創建新表,把原表的數據同步到新表內,然後刪除原表,把新表的表名修改為原表表名。
2 業務背景
大部分表的設計包含json字段,由於json字段不能之間創建索引,導致慢SQL。針對這一問題,目前的解決方案是表內添加不同條件的虛擬列。在虛擬列字段上創建索引。虛擬列分為VIRTUAL和STORED兩種格式。其中VIRTUAL類型的列在之前mysql5.x時會引發Taurus的bug。目前環境都是基於mysql8.0,依然建議使用STORED類型虛擬列。STORED類型虛擬列會佔用磁盤空間存儲數據,所以select類型的SQL會變快,但是寫入會變慢。VIRTUAL類型的虛擬列不實際佔用磁盤空間,每次查詢時會按照定義計算,對查詢語句性能提升不明顯,同時也不影響插入SQL的性能。
3 使用時注意事項
3.1 命令分--dry-run 和--execte兩步
--dry-run不會實際執行
pt-online-schema-change --user=hose_change_ddl --password='xxxx' --host=xxx --port=3306 D=ekb460mix,t=flow_flow_bk09241039 --alter "xxxx" --recursion-method=none --dry-run --print --charset=utf8mb4
--execute會實際執行
pt-online-schema-change --user=hose_change_ddl --password='xxxx' --host=xxx --port=3306 D=ekb460mix,t=flow_flow_bk09241039 --alter "xxxx" --recursion-method=none --execute --print --charset=utf8mb4
3.2 polar數據庫執行時 --host後面指定數據庫的主節點,不要制定讀寫節點。
pt內部的某些主從判斷的指令和polar代理有兼容性問題。polar的架構有自己特殊性
3.3 --alter 同時添加多個列時,如果表太大可以分開多次添加。
執行會報資源或者表大問題。
3.4 添加虛擬列
3.4.1 執行過程中VIRTUAL字段的虛擬列被截斷也沒關係
比如code字段本來長度是code varchar(20) ........VIRTUAL類型,在--dry-run命令沒有報錯,--execute命令後發現被截斷了,但是添加列依然成功了。這個報錯不影響,因為在查查詢時會再生成。
3.5 VIRTUAL改為STORED
3.5.1 不可以直接執行MODIFY,需要先drop,然後add。
示例:
---錯誤
pt-online-schema-change --user=hose_change_ddl --password='xxxx' --host=10.0.6.43 --port=3306 D=ekb460mix,t=flow_flow_bk09241039 --alter "MODIFY COLUMN code varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin GENERATED ALWAYS AS (json_unquote(json_extract(\`\$json\`, _utf8mb4'\$.\"form\".\"code\"'))) STORED" --recursion-method=none --dry-run --print --charset=utf8mb4
--正確示例
pt-online-schema-change --user=hose_change_ddl --password='xxxx' --host=10.0.6.43 --port=3306 D=ekb460mix,t=flow_flow_bk09241039 --alter "DROP COLUMN code, ADD COLUMN code varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin GENERATED ALWAYS AS (json_unquote(json_extract(\`\$json\`,_utf8mb4'\\$.\"form\".\"code\"'))) STORED" --recursion-method=none --dry-run --print --charset=utf8mb4
3.5.2 已有數據字段的長度必須<=修改後設置的字段長度(code varchar(20) )
示例
code字段定義為code varchar(20) ........VIRTUAL,但數據超長了。
執行結果:
注意:示例中code字段的長度是code varchar(20) ,但是實際數據中長度有40的,當執行execute命令後,顯示是成功了,但查看修改後的表結構發現依然是VIRTUAL。
此時需要將code字段的長度定義為超過最大數據長度即可。如
pt-online-schema-change --user=hose_change_ddl --password='xxxx' --host=10.0.6.43 --port=3306 D=ekb460mix,t=flow_flow_bk09241039 --alter "DROP COLUMN code, ADD COLUMN code varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin GENERATED ALWAYS AS (json_unquote(json_extract(\`\$json\`,_utf8mb4'\\$.\"form\".\"code\"'))) STORED" --recursion-method=none --dry-run --print --charset=utf8mb4
再次查看錶結構發現已經修改成功。