我可以讓 postgres 更詳細地告訴我它在做什麼嗎?
我正在嘗試
ALTER TABLE
在實時數據庫上使用(不是在生產中,只是在開發盒中四處尋找並嘗試學習一些東西)這是我正在嘗試的命令:
psql -h $IP -p 5432 -U $DBUSER -d $DBNAME \ -c "alter table request alter column sources set data type text;"
發生的事情是……什麼都沒有。postgres 只是靜靜地坐在那裡很多很多分鐘,直到我放棄並取消它:
^CCancel request sent ERROR: canceling statement due to user request
我所做的一些閱讀表明這應該很快,因為它沒有添加任何繁重的約束,例如
UNIQUE
外鍵或任何東西。表中的行少於 100 行,因此即使這是一個繁重的命令,它仍然應該相對較快地完成。現有的類型是
varchar(1000)
,難道只是pg從varchar轉換為text既困難又慢?我認為這將是一個微不足道的轉換,基本上只是取消了 1000 個字元的限制。表是否可能以某種方式被鎖定並且我的命令只是暫停,等待其他事情完成?我將如何檢查?如果是這樣,我會怎麼說“沒有 pg,這個是重要的,鎖定其他所有內容”。
一般來說,如果我能讓 pg 列印出一些調試來說明長時間的暫停是由於繁重的處理還是只是在等待釋放鎖,那就太好了。
裡面有 29 行,
pg_locks
其中一些確實說ExclusiveLock
,但除此之外,我不確定如何解釋這些資訊。Postgresql 版本是
9.3.9-0ubuntu0.14.04
(即 Ubuntu Trusty 可用的最新版本)。這是塊報告: http: //paste.ubuntu.com/12243226/
潛在相關:我的數據庫使用者是燒瓶/sqlalchemy,也許它是將選擇語句定義為阻塞表的那個。9 個語句被阻塞並且都說“where request_id = 1”的事實很奇怪,因為 request_id 1 前段時間被刪除了。這是某種懸空的幽靈查詢嗎?我怎樣才能清除這個?
這是 pg_stat_activity:http ://paste.ubuntu.com/12243295/
輸出中顯示的
idle in transaction
狀態pg_stat_activity
通常意味著有些東西以 開始交易BEGIN
,做了一些工作,然後沒有發出 ,COMMIT
因此交易完成。這具有使語句獲取的鎖保持不變的效果ACCESS SHARE
,SELECT
這會阻止ALTER TABLE
您嘗試執行的語句獲取ACCESS EXCLUSIVE
更改表中每一行的列類型所需的鎖。從某種意義上說,它們只能被視為“幽靈查詢”,因為它們正在等待
COMMIT
或ROLLBACK
可能永遠不會出現的答案。但是它們是有問題的,儘管如此,正如您所想的那樣。您的應用程序中的某個地方可能存在一個錯誤,導致所有這些連接都打開並等待送出。我肯定會檢查一下,看看程式碼塊是否沒有終止
COMMIT
.更常見的是(根據我的經驗,當然是 YMMV),人們用 a 開始數據庫會話
BEGIN
,做一些工作,然後去吃午飯,從不關閉他們的會話。最好從源頭上解決問題,但如果您絕對、肯定需要現在就做某事,
pg_cancel_backend
而且pg_terminate_backend
方法也不錯。在評論您的答案時,我會專門選擇 的狀態
idle in transaction
,而不是LIKE '%idle%'
因為這些是導致您的問題的原因。idle
狀態後端只是耐心地等待新的客戶端命令,並且最後執行了一個命令ROLLBACK
。您可以查看Explicit Locking文件以獲取有關什麼阻止什麼的更多資訊。
的描述
idle-in-transaction
在Unix 監控工具部分供參考。
pg_cancel_backend
和pg_stat_activity
issueSIGINT
和SIGTERM
信號,以及這些信號的影響(以及有關其他信號的警告)記錄在伺服器關閉部分。希望這有助於解釋您所看到的並闡明您的奧秘。=)