作者:任坤
現居珠海,先後擔任專職 Oracle 和 MySQL DBA,現在主要負責 MySQL、mongoDB 和 Redis 維護工作。
本文來源:原創投稿
*愛可生開源社群出品,原創內容未經授權不得隨意使用,轉載請聯絡小編並註明來源。
1、背景
線上有套10節點clickhouse叢集,5分片 * 2副本,版本19.7.3。
開發執行一個建立分散式表的操作,9個節點都成功返回,有個節點報錯,返回資訊如下:
Code: 159. DB::Exception: Received from 127.0.0.1:9000. DB::Exception: Wa
tching task /clickhouse/task_queue/ddl/query‐0003271440 is executing longer
than distributed_ddl_task_timeout (=180) seconds. There are 1 unfinished ho
sts (0 of them are currently active), they are going to execute the query i
n background.
2、診斷
登入該節點檢視show processlist,正在執行1個分散式ddl,該ddl已經執行100多個小時,應該是卡住了。
clickhouse的分散式ddl是序列執行的,每次將任務儲存到zookeeper
的/clickhouse/task_queue/ddl目錄,按照FIFO排列。
對於每個節點,只有當前的ddl執行完畢,後面的才能被呼叫。
select * from zookeeper where path='/clickhouse/task_queue/ddl' order by ctime desc\G
剛剛發起的建立分散式表ddl排在第一位,上述截圖中的optimize table排在第23,說明被其阻塞的ddl有22條之多,開發也確認最近兩天的ddl任務在該節點上都沒有成功。
嘗試將其kill,等待幾個小時仍然沒有效果。
加sync關鍵字,直接卡住。
嘗試重啟ck例項也卡住,最後只能Kill -9。
重啟例項後該任務依然存在,而且執行了10多分鐘沒有要結束的意思,kill操作仍然無效。
既然這個ddl無法繞過,執行的時候又長時間不結束,只能曲線救國,重新命名該表讓其臨時消失一會。
rename table log_catch_data_local to log_catch_data_local1;
optimize table當即返回,並且其後22個ddl也很快執行完畢,最後再將其重新命名回原表。
此時再次執行optimize table,只需5s便成功返回,該問題解決。
3、總結
clickhouse的分散式ddl在每個節點是FIFO序列執行的,任意1個ddl卡住了都會阻塞後續任務。
本例中的卡住的ddl是optimize table,可以通過重新命名錶跳過;如果是增刪列,可以在rename後手工對該表執行本地ddl。
如果上述方法都不行,可以在出問題的節點將本地表直接drop,等待所有阻塞ddl執行完畢後,重新建立1個空表,會自動從另一個副本中同步資料。
最後,19.x版本已經很舊了,我們在使用過程中遭遇了各種問題,要儘快升級到20.x系列