挿入中にSQLiteエラー「読み取り専用データベースへの書き込みを試みます」?


124

Webサイトに使用しているSQLiteデータベースがあります。問題は、それを試そうとするINSERT INTOと、PDOException

SQLSTATE[HY000]: General error: 8 attempt to write a readonly database

私はサーバーにSSHで接続して権限を確認しましたが、データベースには権限があります

-rw-rw-r--

* nixの権限についてはあまり詳しくありませんが、これは

  • ディレクトリではありません
  • 所有者は読み取り/書き込み権限を持っています(それは私ですls -l
  • グループには読み取り/書き込み権限があります
  • 他のすべてのユーザーは読み取り権限のみを持っています

私はまた、sqlite3プログラムを使用することを知っているあらゆる場所を調べましたが、何も関連性がありませんでした。

PDOがデータベースを開こうとしている権限がわからなかったので、

chmod o+w supplies.db

今、私は別のものを得ますPDOException

SQLSTATE[HY000]: General error: 14 unable to open database file

しかし、データベースが開いたINSERTクエリを実行しようとしたときにのみ発生します。

何が起こっているのかについてのアイデアはありますか?


基本的にhttpd(apache> php> PDO)はあなたではないため、ファイルを所有していないため、書き込み権限がありません...興味深い...
SparK

sudo chgrp www-data test.dbパーミッションを追加するとうまく
いき

回答:


305

結局のところような問題は、PDO SQLiteのドライバを使用すると、書き込み操作を行おうとしている場合(ことが必要ということでINSERTUPDATEDELETEDROP、など)、その内のデータベースフォルダ存在が実際と同様に、書き込み権限を持っている必要がありますデータベースファイル。

この情報は、PDO SQLiteドライバーのマニュアルページの一番下にあるコメントに記載されています


9
また、SELinux(インストールされている場合)を強制してはなりません。それを理解するのに1日半かかりました。
Steve V.

1
うーん、申し訳ありませんが、感謝しましたが、一時的に問題を解決しました。主な問題は、私のwww-dataユーザーがwww-dataグループに含まれていないことでした。
Dorian

5
私が知っているように、ジャーナリングファイルが作成されるとdb自体が作成されるため、格納フォルダは書き込み可能でなければなりません。ウェブサーバーと同じユーザーにするには、ファイルのコンテンツを別の作成されたアドホックにコピーしてみてください。
lcapra 2011

4
また、dbファイルとそれが存在するディレクトリは、Linuxボックスの「www-data」が所有している必要があります。
anisbet 2015年

1
現在、sqlite3には3つのファイル、.dba .db-shm、a 、aがあり、.db-walもちろん3つのファイルの親ディレクトリがあります。これらは、プログラムを実行するユーザーがすべて書き込み可能である必要があります。
Marcos Dione、2016

17

これは、SQLiteファイル自体の所有者がスクリプトを実行しているユーザーと同じでない場合に発生する可能性があります。ディレクトリパス全体(途中の各ディレクトリ)に書き込めない場合にも、同様のエラーが発生する可能性があります。

SQLiteファイルの所有者は誰ですか?君は?

スクリプトは誰として実行されていますか?アパッチか誰も?


1
SQLiteファイルを所有していますが、スクリプトの実行者がわかりません。どうすれば確認できますか?(覚えておいてください、これは共有ホスト上にあり、私は権限が制限されています)
オースティンハイド

1
ああ、それは物事をより楽しくします。共有ホスティングを使用している場合、スクリプトが「nobody」または「apache」として実行される可能性が非常に高くなります。スクリプトでファイル(file_put_contents('./foo.txt', 'Hello, world');)を作成します。これにより、実行しているユーザーが表示されます。おそらく、スクリプトでSQLiteデータベースを作成する必要があります。現在のファイルに既にデータがある場合、これは楽しい練習になるかもしれません...
Charles

いい考えですが、行けません。PHPを実行しているユーザーには書き込み権限がないため、ファイルを作成できません。とにかく、PHPは現在実行しているユーザーを取得できますか?
オースティンハイド

唯一の方法は、POSIX-yシステムでデフォルトで有効になっているPOSIX拡張を経由することです。ただし、ホスティングプロバイダーがR'd TFMを使用していて、それを無効にしている場合があります。
Charles

まあ、彼らは大丈夫です、TFMをRしました。posix_getuid()どちらも機能しません。
オースティンハイド

6

私にとっての問題は、権限ではなくSELinuxの強制でした。「読み取り専用データベース」エラーは、受け入れられた回答に関するコメントでスティーブVが行った提案に従って、強制無効にすると解消されました

echo 0 >/selinux/enforce

このコマンドを実行すると、すべてが意図したとおりに機能しました(CentOS 6.3)。

私が遭遇した特定の問題は、グラファイトのセットアップ中に発生しました。私は、apacheユーザーが所有していて、私のGraphite.dbとその親ディレクトリの両方に書き込むことができることをトリプルチェックしました。しかし、SELinuxを「修正」するまで、私が得たのは、以下の影響に対するスタックトレースだけでした。DatabaseError:読み取り専用データベースに書き込もうとしました


8
SELinuxはセキュリティ対策であるため、正当な理由がない限り無効にしないでください。そもそもSELinuxがブロックしている理由を理解し、無効にするのではなく、正しく設定する方が良いでしょう。
イェンスウェガー2014

5

これは、SELinuxが原因である可能性があります。SELinuxを完全に無効にしたくない場合は、dbディレクトリのfcontextをhttpd_sys_rw_content_tに設定する必要があります。

semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/railsapp/db(/.*)?"
restorecon -v /var/www/railsapp/db

4

Androidシステムのデータベースに書き込もうとしたときに、このエラーが発生しました。

どうやらsqlite3には、データベースファイルとそれを含むディレクトリ(@ austin-hydeがすでに彼の回答で述べたように)への書き込み権限だけでなく、環境変数も必要です TMPDIRが(おそらく書き込み可能な)ディレクトリを指す必要があります。

私のAndroidシステムでは、それを TMPDIR="/data/local/tmp"、スクリプトは期待どおりに実行されます

編集:

環境変数を設定できない場合は、ここにリストされている他の方法のいずれかを使用できます:https : //www.sqlite.org/tempfiles.html#temporary_file_storage_locations likePRAGMA temp_store_directory = 'directory-name';


2

Windows 7でIISから同じエラーが発生しました。このエラーを修正するには、sqliteデータベースファイルのIUSRアカウントにフルコントロールのアクセス許可を追加する必要がありました。IISの代わりにwebmatrixでsqliteを使用する場合は、権限を変更する必要はありません。


2

要約すると、データベースファイル(* .db)をサブフォルダーに配置することで問題を解決しました。

  • サブフォルダーとその中のデータベースファイルは、www-dataグループのメンバーである必要があります。
  • www-dataグループでは、サブフォルダーとデータベースファイルに書き込む権限が必要です。


0

私が使用した:

echo exec( 'whoami');

スクリプトを実行しているユーザー(ユーザー名など)を確認し、次のようにユーザーにアプリケーションディレクトリ全体へのアクセス許可を付与します。

sudo chown -R:username / var / www / html / myapp

これが誰かを助けることを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.