Hatena::ブログ(Diary)

ablog このページをアンテナに追加 RSSフィード

2018-01-21

PostgreSQL で "Too many open files in system" が発生する

事象

以下のエラーがログに出力される。

Too many open files in system

考察

Linuxカーネルパラメータ fs.file-max はシステム全体でオープンできるファイルディスクリプタ数、つまり PostgreSQL 以外がオープンするファイルディスクリプタも含まれる。

PostgreSQL がオープンするファイルディスクリプタ数は max_files_per_process でサーバプロセスごとにオープンできる上限を設定できる。ソケットを使うときもファイルディスクリプタをオープンするので max_connections の数もファイルのディスクリプタ数に関係する。


参考

max_files_per_process (integer)

それぞれのサーバプロセスが同時にオープンできるファイル数の最大値をセットします。 デフォルトは1000ファイルです。 もしもカーネルプロセス毎の安全制限を強要している場合、この設定を気にかける必要はありません。 しかし、いくつかのプラットフォーム(特にほとんどのBSDシステム)では、もし多くのプロセス全てがそれだけ多くのファイルを開くことを試みたとした場合、実際にサポートできるファイル数より多くのファイルを開くことを許しています。もしも「Too many open files」エラーが発生した場合、この設定を削減してみてください。 このパラメータサーバ起動時にのみ設定可能です。

19.4. 資源の消費

3.2.1. カーネルパラメータ

Linux カーネルパラメータ設定により、PostgreSQL が使用するシステムのリソースの制限を変更することができます。システム全体でオープン可能なファイル数や接続数に応じたセマフォの全体数、共有メモリサイズなど、規模に応じたシステムリソース容量の設定を行います。カーネルパラメータの設定値については、マニュアル9を参考にしてください。

カーネルパラメータ説明関連する PostgreSQLパラメータ
fs.file-maxシステム全体で使用可能なファイルディスクリプタ数を指定する。PostgreSQL のバックエンドプロセスが同時にオープンするファイル数の設定と最大接続数から、PostgreSQL要求するファイルディスクリプタ数を確認することができる。max_files_per_process
バックエンドプロセス要求する最大ファイルディスクリプタ数。
max_connections
DB への最大接続数。
https://www.pgecons.org/wp-content/uploads/PGECons/2013/WG2/11_PerformanceTuning.pdf

2017-12-29

nethogs でプロセス別の通信量を調べる

nethogs はネットワークの top コマンド的なもので通信量の多いプロセスをランキング表示して、秒間通信量も見ることができる。

f:id:yohei-a:20171229222742p:image


インストール

sudo yum -y install gcc-c++ libpcap-devel.x86_64 libpcap.x86_64 ncurses*
git clone https://github.com/raboof/nethogs
cd nethogs
make
sudo make install

使ってみる

sudo /usr/local/sbin/nethogs

参考

NetHogs is a small 'net top' tool. Instead of breaking the traffic down per protocol or per subnet, like most tools do, it groups bandwidth by process.

NetHogs does not rely on a special kernel module to be loaded. If there's suddenly a lot of network traffic, you can fire up NetHogs and immediately see which PID is causing this. This makes it easy to identify programs that have gone wild and are suddenly taking up your bandwidth.

Since NetHogs heavily relies on /proc, most features are only available on Linux. NetHogs can be built on Mac OS X and FreeBSD, but it will only show connections, not processes.

https://github.com/raboof/nethogs

追記(2018/2/17):

Since NetHogs heavily relies on /proc, most features are only available on Linux. NetHogs can be built on Mac OS X and FreeBSD, but it will only show connections, not processes.

https://github.com/raboof/nethogs

macOS Sierra 10.12.6 でも普通に使えた。

% git clone https://github.com/raboof/nethogs
% cd nethogs
% make
% sudo make install
% sudo /usr/local/sbin/nethogs

2017-12-11

RDS PostgreSQL で大量にセッションを張った場合のメモリ使用量を調べる

RDS PostgreSQL に pgbench で 2000 セッション張って負荷をかけてみたところ、12.5GBほどあった空きメモリを使い尽くして、2GB以上スワップした。

プロセス自体のメモリ、ワーク領域、ページテーブル(PTE)などで1セッションあたり、6MB以上は使っている計算になる。


検証

pgbench を以下で2つ同時に実行して、負荷をかけた。

% pgbench -r -c 1000 -j 1000 -t 100000 -U awsuser -h pg-m4xlarge-master-6.******.ap-northeast-1.rds.amazonaws.com -d mydb

結果

AWSマネジメントコンソールの CloudWatch メトリックスで確認してみた。

f:id:yohei-a:20171211190130p:image:w640

f:id:yohei-a:20171211190125p:image:w640

f:id:yohei-a:20171211190121p:image:w640


環境

  • db.m4.xlarge*1
    • vCPU: 4
    • メモリ: 16GB

参考

ローカルメモリ量 = プロセスのスタック領域
                  + 一時テーブルを使用するデータベースセッションで消費されるメモリ
                  + ソートやハッシュテーブル操作を行うデータベースセッションで消費されるメモリ
                  + 保守操作で消費されるメモリ
                  + プロセス毎に消費される基礎メモリ
                  + データアクセスの準備のために消費されるメモリ
プロセス毎に消費される基礎メモリ
  =  3メガバイト × (max_connections + autovacuum_max_workers + 9)
H.1 FUJITSU Enterprise Postgresで使用するメモリの見積り式

2017-12-07

Aurora MySQL互換に LOAD コマンドで CSV ファイルをロードしようとすると "ERROR 1148 (42000)" で失敗する

Aurora MySQL互換というより MySQL の話です。


事象

  • mysql クライアントで接続して、LOAD DATA ステートメントで CSV ファイルをロードしようとすると、"ERROR 1148 (42000): The used command is not allowed with this MySQL version" と怒られる。
% mysql  --local-infile -h aurora01.cluster-******.ap-northeast-1.rds.amazonaws.com -u awsuser -p
mysql> LOAD DATA LOCAL INFILE '.test.csv' INTO TABLE TEST FIELDS TERMINATED BY ',' ENCLOSED BY '"';
ERROR 1148 (42000): The used command is not allowed with this MySQL version

原因

  • セキュリティ上の理由でデフォルトで LOAD DATA ステートメントが無効なため。

解決策

  • --local-infile オプションをつけて mysql クライアントで接続してロードする。
% mysql  --local-infile -h aurora01.cluster-******.ap-northeast-1.rds.amazonaws.com -u awsuser -p
mysql LOAD DATA LOCAL INFILE 'test.csv' INTO TABLE TEST FIELDS TERMINATED BY ',' ENCLOSED BY '"';

参考

LOAD DATA ステートメントの LOCAL バージョンのサポートに関しては、セキュリティーについての潜在的な問題が 2 つあります。

  • クライアントホストからサーバーホストへのファイルの送信は、MySQL サーバーによって開始されます。理論的には、パッチ適用済みサーバーを構築して、LOAD DATA ステートメントでクライアントによって指定されたファイルでなく、サーバーが選択するファイルを転送するようサーバーがクライアントプログラムに指示するようにすることができます。そのようなサーバーは、クライアントユーザーが読み取りアクセス権を持つクライアントホスト上のすべてのファイルにアクセスできます。
  • クライアントが Web サーバーから接続する Web 環境で、ユーザーは LOAD DATA LOCAL を使用して、Web サーバプロセスが読み取りアクセス権を持つすべてのファイルを読み取ることができます (ユーザーが SQL Server に対してあらゆるコマンドを実行できる場合)。この環境では、MySQL サーバーを基準にしたときのクライアントは実際には Web サーバーであって、Web サーバーに接続するユーザーによって実行されているリモートプログラムではありません。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 6.1.6 LOAD DATA LOCAL のセキュリティーの問題

You can specify that as an additional option when setting up your client connection:

mysql -u myuser -p --local-infile somedatabase

This is because that feature opens a security hole. So you have to enable it manually in case you really want to use it.

sql - ERROR 1148: The used command is not allowed with this MySQL version - Stack Overflow

mysql コマンド行クライアントの場合、--local-infile[=1] オプションを指定することによって LOAD DATA LOCAL を有効にするか、--local-infile=0 オプションを指定することによってこれを無効にします。mysqlimport の場合、ローカルデータファイルのロードはデフォルトでオフになっており、--local または -L オプションを使用してこれを有効にします。いずれの場合でも、ローカルロード操作を正常に使用するには、サーバーがこの操作を許可していることが必要。

MySQL :: MySQL 5.6 リファレンスマニュアル :: 6.1.6 LOAD DATA LOCAL のセキュリティーの問題