最近審批了一個pg數據庫ddl表結構變更的工單
變更SQL如下所示:
ALTER TABLE t_table_bind_info ALTER COLUMN third_user_id TYPE varchar(128);
原先長度小於128,本次變更為擴容varchar長度。
審批沒多久後發現有CPU等告警,立即查看各監控指標和錯誤日志、慢日志等信息。
發現監控多項指標異常
![](https://news.xinpengboligang.com/upload/keji/ee0a6ceb2e7b7ec5caa61788fb7da1c3.jpeg)
CPU利用率飆升
![](https://news.xinpengboligang.com/upload/keji/a82f5ea302075894bd81f4f5c02ffd64.jpeg)
active_session活動連接從0漲到11左右
![](https://news.xinpengboligang.com/upload/keji/9deaa17145580196224dfa9994030780.jpeg)
fetch和return都積聚增加
![](https://news.xinpengboligang.com/upload/keji/82f3046556db86d1a28af05d32afa9d4.jpeg)
也出現了慢查詢
1,DDL執行結束後立即出現錯誤日志 ERROR: cached plan must not change result type
2,30秒之後出現業務慢日志 ERROR: canceling statement due to statement timeout 信息。
我收到CPU告警信息後立即去手動analyze收集剛剛ddl的表統計信息,之後CPU,慢查詢等立即恢復正常,業務影響消失。
其實這是兩個問題,第一個關於ERROR: cached plan must not change result type報錯,原因如下:
PostgreSQL的優化器和Oracle等庫一樣都是比較復雜的,可能會使用綁定變量,減少sql parser, plan的開銷,但是當我們做數據庫表結構的DDL變更時,緩存中的執行計劃與結果類型就會不匹配,就會報ERROR: cached plan must not change result type報錯,關於這個報錯有多種解決辦法如重啟業務程序,殺掉數據庫會話連接,deallocate the prepare等方法。但是由於當前各業務都是使用的ORM框架生成的SQL,另外我們屬於OLTP在線業務,肯定是不能隨意做上述操作的,我們能做的隻能是在業務相對低峰期審批執行類似的工單,減少對業務的影響。
第二個報錯ERROR: canceling statement due to statement timeout,是因為執行計劃選擇出現了問題,
超時SQL 條件為WHERE third_user_id = $1 and third_app_type = $2
and third_app_name = $3 and is_delete = false order by update_time desc limit 1
third_app_type長度變更後導致執行計劃走到order by update_time索引上,從而引起慢查詢,看起來有必要在業務DDL工單執行完畢後再去自動analyze 一下目標表了,這樣可以減少類似問題的發生,接下來需要盡快優化這一步。