Heroku 上の Django アプリで django_session が溢れた

ある日 HHTQA が 500 を返して動かなくなってた.

$ heroku logs

の末尾にあやしいメッセージが.

OperationalError: (1142, "INSERT command denied to user 'user'@'hostname' for table 'django_session'")

MySQL の権限が変わるわけがない (ClearDB という add-on なので, ユーザとかは俺はいじれない) し, MySQLWorkbench では同じユーザで見れているので, 権限が根本原因ではない.

MySQLWorkbench で色々見てみると django_session というテーブルが肥大化している. テーブル名や expire_date というカラム名から, 明らかに不要なデータが溜まっている.

SELECT count(*) FROM django_session; -- 15677

このテーブル名で検索すると https://docs.djangoproject.com/en/dev/topics/http/sessions/?from=olddocs/#clearing-the-session-table という情報が見付かり, 手作業で削除することもできるそうだ.

heroku コマンド使って, Heroku 上の環境で削除操作を行った.

$ heroku run find / -name django-admin.py
Running find / -name django-admin.py attached to terminal... up, run.1
find: `/proc/tty/driver': Permission denied
find: `/proc/1/task/1/fd': Permission denied
find: `/proc/1/task/1/fdinfo': Permission denied
find: `/proc/1/fd': Permission denied
find: `/proc/1/fdinfo': Permission denied
find: `/lost+found': Permission denied
find: `/etc/ssl/private': Permission denied
/app/.heroku/venv/bin/django-admin.py
/app/.heroku/venv/lib/python2.7/site-packages/django/bin/django-admin.py

$ heroku run .heroku/venv/bin/django-admin.py cleanup
DJANGO_SETTINGS_MODULE が無いと怒られるので設定.

あくまでモジュール名. ファイル名ではないので注意.
$ heroku config:add DJANGO_SETTINGS_MODULE=settings
$ heroku run ls '$DJANGO_SETTINGS_MODULE'
確認
$ heroku run .heroku/venv/bin/django-admin.py cleanup
SELECT count(*) FROM django_session; -- 1933

予想通り django_session テーブルが小さくなったので, Heroku アプリを再起動.

$ heroku restart
$ heroku logs

まだ何かエラーが出る. 以下 heroku logs の結果.

2012-07-14T12:52:29+00:00 heroku[web.1]: Starting process with command `python manage.py run_gunicorn 0.0.0.0:33646`
2012-07-14T12:52:30+00:00 app[web.1]: Unknown command: 'run_gunicorn'
2012-07-14T12:52:30+00:00 app[web.1]: Type 'manage.py help' for usage.
2012-07-14T12:52:31+00:00 heroku[web.1]: Process exited with status 1
2012-07-14T12:52:31+00:00 heroku[web.1]: State changed from starting to crashed

どうも手元の manage.py と Heroku 上の manage.py が違っている予感. python manage.py help で出てくる subcommand の種類が, 手元と Heroku 上で異なる.

$ heroku run python ./manage.py help
Running python ./manage.py help attached to terminal... up, run.1
Usage: manage.py subcommand [options] [args]

Options:
  -v VERBOSITY, --verbosity=VERBOSITY
                        Verbosity level; 0=minimal output, 1=normal output, 2=all output
  --settings=SETTINGS   The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used.
  --pythonpath=PYTHONPATH
                        A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
  --traceback           Print traceback on exception
  --version             show program's version number and exit
  -h, --help            show this help message and exit

Type 'manage.py help <subcommand>' for help on a specific subcommand.

Available subcommands:
  cleanup
  compilemessages
  createcachetable
  dbshell
  diffsettings
  dumpdata
  flush
  inspectdb
  loaddata
  makemessages
  reset
  runfcgi
  runserver
  shell
  sql
  sqlall
  sqlclear
  sqlcustom
  sqlflush
  sqlindexes
  sqlinitialdata
  sqlreset
  sqlsequencereset
  startapp
  syncdb
  test
  testserver
  validate

と, run_gunicorn subcommand が無い. こりゃ動かん……

V 先輩のブログ記事 を参考に gunicorn_django を使ってみる.

$ heroku run ls .heroku/venv/bin/gunicorn_django
Running ls .heroku/venv/bin/gunicorn_django attached to terminal... up, run.1
.heroku/venv/bin/gunicorn_django

$ heroku run .heroku/venv/bin/gunicorn_django -b 0.0.0.0:$PORT settings.py
'$PORT' の部分がローカルで展開されてしまって失敗. やり直し.

$ heroku run '.heroku/venv/bin/gunicorn_django -b 0.0.0.0:$PORT settings.py'
"settings.py" というモジュール名で探しにいくようで, "py" がモジュール名と認識され失敗.

$ heroku run '.heroku/venv/bin/gunicorn_django -b 0.0.0.0:$PORT settings'
Running .heroku/venv/bin/gunicorn_django -b 0.0.0.0:$PORT settings attached to terminal... up, run.1

Error: django project not found
うーん, ちょっと原因が分からない.

モジュール名の代わりにファイル名でやってみた.
$ heroku run '.heroku/venv/bin/gunicorn_django -b 0.0.0.0:$PORT /app/settings.py'
ImportError: Could not import settings '/app/settings.py' (Is it on sys.path?): Import by filename is not supported.
お見通しだった( ´・ω・`

http://stackoverflow.com/questions/10527512/configuring-gunicorn-for-django-on-heroku https://devcenter.heroku.com/articles/django

ここを見てるときにふと思い立って, 起動コマンドを変えてみた.

$ emacs Procfile
web: gunicorn_django -b 0.0.0.0:$PORT
$ git commit -am "..."
$ git push heroku master

お, 起動した!

そしてまた DB アクセスエラーが出た. とりあえず振り出しに戻る.

OperationalError: (1142, "UPDATE command denied to user 'user'@'hostname' for table 'forum_keyvalue'")

んー, MySQLWorkbench で SHOW GRANTS; してみても変なところは見付からないし…… 基本に戻って ClearDB add-on のページ見てみるか, と見てみたら, 単なる契約容量溢れ. 無料の ignite プランでやってたが, 5MB/5MB になってた. あれー, 昨日は 4MB/5MB の表示だったんだけど……

とにかく "Database size meets or exceeds tier quota; database write privileges been disabled. Upgrade your database plan to get more storage." というメッセージもあるので, 有料プランに上げないと. お金の話になるのでちょっととある人に交渉.

(交渉...)

承認下りたので, 有料プランにアップグレード. http://www.cleardb.com/developers/connect/paas/heroku/clojure#1.2.7 を読むと, コマンド一発らしい. (すごい!) データをエクスポートして,

$ heroku addons:upgrade cleardb:punch
----> Upgrading cleardb:punch to glowing-moon-7493... done, v21 ($9.99/mo)

http://glowing-moon-7493.herokuapp.com/ にアクセスして, 無事動いた. 管理画面が簡素になってしまったが, CSS とかだろう. 後回し.

とりあえず対応は終了.

(なんか仕事してる気分になるけど, これで一昨日の深夜に対応を始めてから数時間分の作業. まだまだ対応が遅いな……)

あれ? 再度 heroku run python manage.py help を実行したら, subcommand 増えてるぞ. ??? そもそもさっきは通常どおり動いていなかったんだから, そういうこともあるか. Procfile を前のに戻して再度 push.

$ cat Procfile
web: python manage.py run_gunicorn 0.0.0.0:$PORT
$ git push heroku master

無事見慣れた Django の管理画面が出てきた.

Comments

blog comments powered by Disqus

Licenses