19.13. Управление блокировками #
deadlock_timeout(integer) #Время ожидания блокировки, по истечении которого будет выполняться проверка состояния взаимоблокировки. Эта проверка довольно дорогостоящая, поэтому сервер не выполняет её при всяком ожидании блокировки. Мы оптимистично полагаем, что взаимоблокировки редки в производственных приложениях, и поэтому просто ждём некоторое время, прежде чем пытаться выявить взаимоблокировку. При увеличении значения этого параметра сокращается время, уходящее на ненужные проверки взаимоблокировки, но замедляется реакция на реальные взаимоблокировки. Если это значение задаётся без единиц измерения, оно считается заданным в миллисекундах. Значение по умолчанию — одна секунда (
1s), что близко к минимальному значению, которое стоит применять на практике. На сервере с большой нагрузкой имеет смысл увеличить его. В идеале это значение должно превышать типичное время транзакции, чтобы повысить шансы на то, что блокировка всё-таки будет освобождена, прежде чем ожидающая транзакция решит проверить состояние взаимоблокировки. Изменить этот параметр могут только суперпользователи и пользователи с соответствующим правомSET.Когда включён параметр log_lock_waits, данный параметр также определяет, спустя какое время в журнал сервера будут записываться сообщения об ожидании блокировки. Если вы пытаетесь исследовать задержки, вызванные блокировками, имеет смысл уменьшить его по сравнению с обычным значением
deadlock_timeout.max_locks_per_transaction(integer) #В общей таблице блокировок может храниться
max_locks_per_transactionобъектов (например, таблиц) для каждого серверного процесса или подготовленной транзакции, таким образом, в любой момент времени может быть заблокировано не больше этого числа различных объектов. Этот параметр ограничивает среднее число блокировок объектов, используемых каждой транзакцией, отдельные транзакции могут заблокировать и больше объектов, если все они умещаются в таблице блокировок. Заметьте, что это не число строк, которое может быть заблокировано; их количество не ограничено. Значение по умолчанию, 64, как показала практика, вполне приемлемо, но может возникнуть потребность его увеличить, если запросы обращаются ко множеству различных таблиц в одной транзакции, как, например, запрос к родительской таблице со многими потомками. Этот параметр можно задать только при запуске сервера.Для ведомого сервера значение этого параметра должно быть больше или равно значению на ведущем. В противном случае на ведомом сервере не будут разрешены запросы.
max_pred_locks_per_transaction(integer) #В общей таблице предикатных блокировок хранится
max_pred_locks_per_transactionобъектов (например, таблиц) для каждого серверного процесса или подготовленной транзакции, таким образом, в один момент времени может быть заблокировано не больше этого числа различных объектов. Этот параметр ограничивает среднее число блокировок объектов, используемых каждой транзакцией; отдельные транзакции могут заблокировать и больше объектов, если все они умещаются в таблице блокировок. Заметьте, что это не число строк, которое может быть заблокировано; их количество не ограничено. Значение по умолчанию, 64, как показала практика, вполне приемлемо, но может возникнуть потребность его увеличить, если запросы обращаются ко множеству различных таблиц в одной сериализуемой транзакции, как, например, запрос к родительской таблице со многими потомками. Этот параметр можно задать только при запуске сервера.max_pred_locks_per_relation(integer) #Этот параметр определяет, для скольких страниц или кортежей одного отношения могут устанавливаться предикатные блокировки, прежде чем вместо них будет затребована одна блокировка для всего отношения. Значения, большие или равные нулю, задают абсолютный предел, а с отрицательным значением пределом будет значение max_pred_locks_per_transaction, делённое на модуль данного. По умолчанию действует значение -2, что даёт то же поведение, что наблюдалось в предыдущих версиях Postgres Pro. Этот параметр можно задать только в файле
postgresql.confили в командной строке при запуске сервера.max_pred_locks_per_page(integer) #Этот параметр определяет, для скольких строк на одной странице могут устанавливаться предикатные блокировки, прежде чем вместо них будет затребована одна блокировка для всей страницы. Значение по умолчанию — 2. Этот параметр можно задать только в файле
postgresql.confили в командной строке при запуске сервера.lwlock_shared_limit(integer) #Задаёт количество последовательно запрашиваемых разделяемых блокировок LWLock, при котором включается «справедливый» режим. В этом режиме запросы разделяемых лёгких блокировок добавляются в очередь, а не получают блокировку немедленно, что позволяет получить исключительные блокировки LWLock за разумное время и тем самым избежать их подавления. При небольших значениях этого параметра исключительные блокировки будут получаться гораздо быстрее, но могут возникнуть значительные издержки. С увеличением этого значения снижаются издержки, но уменьшается и ускорение. Обычно со значением, равным 16, достигается ощутимое ускорение при минимальных издержках. Значение по умолчанию — 0 (это поведение отключено). Этот параметр можно задать только в
postgresql.confили в командной строке при запуске сервера.log2_num_lock_partitions(integer) #Этот параметр определяет, на сколько секций будет делиться общая таблица блокировок. Для получения фактического количества секций 2 возводится в заданную степень. Значение по умолчанию — 4, ему соответствует 16 секций; максимальное значение — 8. Этот параметр можно задать только в файле
postgresql.confили в командной строке при запуске сервера.num_xloginsert_locks(integer) #Задаёт количество блокировок вставки при одновременной записи в журнал предзаписи (WAL). Параметр используется для повышения эффективности записи в WAL. Высокое значение позволяет выполнять больше добавлений одновременно, но при этом увеличивает нагрузку на процессор во время сброса WAL на диск, так как требуется обработать все блокировки. Возможные значения: от
1до64. Значение по умолчанию —8. Задать этот параметр можно только в файлеpostgresql.conf.
19.13. Lock Management #
deadlock_timeout(integer) #This is the amount of time to wait on a lock before checking to see if there is a deadlock condition. The check for deadlock is relatively expensive, so the server doesn't run it every time it waits for a lock. We optimistically assume that deadlocks are not common in production applications and just wait on the lock for a while before checking for a deadlock. Increasing this value reduces the amount of time wasted in needless deadlock checks, but slows down reporting of real deadlock errors. If this value is specified without units, it is taken as milliseconds. The default is one second (
1s), which is probably about the smallest value you would want in practice. On a heavily loaded server you might want to raise it. Ideally the setting should exceed your typical transaction time, so as to improve the odds that a lock will be released before the waiter decides to check for deadlock. Only superusers and users with the appropriateSETprivilege can change this setting.When log_lock_waits is set, this parameter also determines the amount of time to wait before a log message is issued about the lock wait. If you are trying to investigate locking delays you might want to set a shorter than normal
deadlock_timeout.max_locks_per_transaction(integer) #The shared lock table has space for
max_locks_per_transactionobjects (e.g., tables) per server process or prepared transaction; hence, no more than this many distinct objects can be locked at any one time. This parameter limits the average number of object locks used by each transaction; individual transactions can lock more objects as long as the locks of all transactions fit in the lock table. This is not the number of rows that can be locked; that value is unlimited. The default, 64, has historically proven sufficient, but you might need to raise this value if you have queries that touch many different tables in a single transaction, e.g., query of a parent table with many children. This parameter can only be set at server start.When running a standby server, you must set this parameter to have the same or higher value as on the primary server. Otherwise, queries will not be allowed in the standby server.
max_pred_locks_per_transaction(integer) #The shared predicate lock table has space for
max_pred_locks_per_transactionobjects (e.g., tables) per server process or prepared transaction; hence, no more than this many distinct objects can be locked at any one time. This parameter limits the average number of object locks used by each transaction; individual transactions can lock more objects as long as the locks of all transactions fit in the lock table. This is not the number of rows that can be locked; that value is unlimited. The default, 64, has historically proven sufficient, but you might need to raise this value if you have clients that touch many different tables in a single serializable transaction. This parameter can only be set at server start.max_pred_locks_per_relation(integer) #This controls how many pages or tuples of a single relation can be predicate-locked before the lock is promoted to covering the whole relation. Values greater than or equal to zero mean an absolute limit, while negative values mean max_pred_locks_per_transaction divided by the absolute value of this setting. The default is -2, which keeps the behavior from previous versions of Postgres Pro. This parameter can only be set in the
postgresql.conffile or on the server command line.max_pred_locks_per_page(integer) #This controls how many rows on a single page can be predicate-locked before the lock is promoted to covering the whole page. The default is 2. This parameter can only be set in the
postgresql.conffile or on the server command line.lwlock_shared_limit(integer) #Specifies the number of sequential shared LWLocks held before switching to the fair mode. In the fair mode, would-be shared lockers are added to the queue instead of acquiring the lock immediately, which allows to acquire an exclusive LWLock within reasonable time and thus avoid lock starvation. Setting this option to small values allows to acquire exclusive locks much faster, but can cause significant overhead. The larger the value, the lower the overhead and the speedup. As a rule of thumb, setting this option to 16 provides good speedup with minimal overhead. The default is 0 (the option is disabled). This parameter can only be set in the
postgresql.conffile or on the server command line.log2_num_lock_partitions(integer) #This controls how many partitions the shared lock tables are divided into. Number of partitions is calculated by raising 2 to the power of this parameter. The default value is 4, which corresponds to 16 partitions, and the maximum is 8. This parameter can only be set in the
postgresql.conffile or on the server command line.num_xloginsert_locks(integer) #Specifies the number of insertion locks on concurrent write-ahead logging. This parameter is used to improve the efficiency of writing write-ahead logs. A higher value allows more insertions to happen concurrently but adds some CPU overhead during WAL flushing, which needs to iterate all the locks. Possible values are from
1to64. The default value is8. This parameter can only be set in thepostgresql.conffile.