Ekleme sırasında 'salt okunur bir veritabanı yazmaya çalışma' SQLite hatası?


124

Bir web sitesi için kullandığım bir SQLite veritabanım var. Sorun şu ki, denediğimde INSERT INTObirPDOException

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

Sunucuya SSH ekledim ve izinleri kontrol ettim ve veritabanı izinlere sahip

-rw-rw-r--

* Nix izinlerine o kadar aşina değilim, ancak bunun şu anlama geldiğinden oldukça eminim:

  • Dizin değil
  • Sahibin okuma / yazma izinleri var (göre bu benim ls -l)
  • Grubun okuma / yazma izinleri var
  • Diğer herkesin yalnızca okuma izinleri vardır

Ayrıca sqlite3programı kullanmayı bildiğim her yere baktım ve alakalı hiçbir şey bulamadım.

PDO'nun veritabanını hangi izinlerle açmaya çalıştığını bilmediğim için yaptım

chmod o+w supplies.db

Şimdi bir tane daha alıyorum PDOException:

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

Ancak YALNIZCA veritabanı açıldıktan sonra bir INSERTsorgu yürütmeye çalıştığımda ortaya çıkıyor .

Neler olduğuna dair bir fikriniz var mı?


temel olarak httpd (apache> php> PDO) siz değilsiniz, bu yüzden dosyanın sahibi değil, bu yüzden yazma izinleri yok ... ilginç ...
SparK

sudo chgrp www-data test.dbbenim için çalışan izinleri ekleyerek
Zippp

Yanıtlar:


305

Olarak çıkıyor sorun, PDO SQLite sürücüsü yazma işlemi yapacağız if (gerektirmesidir INSERT, UPDATE, DELETE, DROP, vb), daha sonra veritabanı klasörünün bulunduğu gerçek, hem de yazma izinlerine sahip olmalıdır veritabanı dosyası.

Bu bilgiyi PDO SQLite sürücü kılavuz sayfasının en altındaki bir yorumda buldum .


9
Ayrıca SELinux (kurulu ise) zorlayıcı olmamalıdır. Bunu anlamam bir buçuk günümü aldı.
Steve V.

1
Üzgünüm, ama teşekkür ederim, ama sorunu geçici olarak çözdü, asıl sorun www-data kullanıcımın www-data grubunda olmamasıydı.
Dorian

5
Bildiğim gibi, içeren klasör yazılabilir olmalıdır, çünkü bir günlük kaydı dosyası yazarken ve dolayısıyla db'nin kendisi oluşturulacaktır. Web sunucusuyla aynı kullanıcıya sahip olmak için, dosyanın içeriğini başka bir oluşturulmuş ad hoc'a kopyalamayı deneyin.
lcapra

4
Ayrıca db dosyası ve içinde bulunduğu dizinin linux kutularındaki 'www-data' tarafından sahip olunması gerekir.
anisbet

1
Şu anda sqlite3 3 dosyaya sahip olabilir .db, a, a .db-shmve a .db-waldosyaları ve tabii ki üçünün ana dizini, programı çalıştıran kullanıcı için tümü yazılabilir olmalıdır.
Marcos Dione

17

Bu, SQLite dosyasının sahibi , komut dosyasını çalıştıran kullanıcıyla aynı olmadığında olabilir . Tüm dizin yolu (yol boyunca her bir dizin anlamına gelir) yazılamazsa benzer hatalar meydana gelebilir.

SQLite dosyasının sahibi kimdir? Sen?

Komut dosyası kim olarak çalışıyor? Apaçi mi Kimse mi?


1
SQLite dosyasının sahibiyim, ancak komut dosyasının kim olarak çalıştığını bilmiyorum. Nasıl öğrenebilirim? (Unutmayın, bu paylaşılan bir sunucuda ve sınırlı izinlerim var)
Austin Hyde

1
Ah, bu işleri daha eğlenceli hale getiriyor. Paylaşılan barındırma hizmetindeyseniz, komut dosyasının "hiç kimse" veya "apache" olarak çalışması çok yüksek bir ihtimaldir. Komut dosyanızın file_put_contents('./foo.txt', 'Hello, world');, kim olarak çalıştığını size gösterecek bir dosya ( ) oluşturmasını sağlayın . Muhtemelen, komut dosyasının SQLite veritabanını oluşturmasına ihtiyaç duyacaksınız. Mevcut dosyanızda zaten veri varsa, bu eğlenceli bir alıştırma olabilir ...
Charles

İyi fikir, ama gitme. PHP gibi çalışan her kimse yazma ayrıcalıklarına sahip değildir, bu nedenle dosyayı oluşturamaz. PHP'nin şu anda hangi kullanıcı olarak çalıştırdığını alabileceği bir şey var mı?
Austin Hyde

Bunun tek yolu , POSIX-y sistemlerinde varsayılan olarak etkinleştirilen POSIX uzantısı gibi görünüyor . Barındırma sağlayıcınız R'd TFM'ye sahip olabilir ve onu devre dışı bırakabilir .
Charles

Pekala, onlar TFM'yi hatırladılar, tamam. posix_getuid()da çalışmıyor.
Austin Hyde

6

Benim için sorun, izinlerden çok SELinux uygulamasıydı . Steve V. tarafından kabul edilen yanıtla ilgili bir yorumda yapılan öneriyi takiben, uygulamayı devre dışı bıraktığımda "salt okunur veritabanı" hatası ortadan kalktı.

echo 0 >/selinux/enforce

Bu komutu çalıştırdıktan sonra, her şey amaçlandığı gibi çalıştı (CentOS 6.3).

Karşılaştığım spesifik sorun, Grafit'in kurulumu sırasında oldu. Apache kullanıcısının hem grafite.db'ye hem de onun üst dizinine yazıp yazamadığını üç kez kontrol ettim. Ama SELinux'u "düzeltene" kadar, sahip olduğum tek şey şunun etkisine yönelik bir yığın izlemesiydi: DatabaseError: salt okunur bir veritabanı yazmaya çalış


8
SELinux bir güvenlik önlemidir, bu nedenle çok iyi bir neden olmadan devre dışı bırakılmamalıdır. SELinux'un neden en başta engellediğini anlamak ve devre dışı bırakmak yerine doğru şekilde yapılandırmak daha iyi olacaktır.
Jens Wegar

5

Bu SELinux'tan kaynaklanabilir. SELinux'u tamamen devre dışı bırakmak istemiyorsanız, fcontext db dizinini httpd_sys_rw_content_t olarak ayarlamanız gerekir.

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

4

Bir Android sistemde bir veritabanına yazmaya çalıştığımda bu hatayı aldım.

Görünüşe göre sqlite3 sadece veritabanı dosyasına ve içerdiği dizine yazma izinlerine (@ austin-hyde cevabında söylendiği gibi) değil, aynı zamanda ortam değişkeninin TMPDIRde (muhtemelen yazılabilir) bir dizini göstermesi gerekiyor.

Android sistemimde ayarladım TMPDIR="/data/local/tmp"ve şimdi betiğim beklendiği gibi çalışıyor :)

Düzenle:

Ortam değişkenlerini ayarlayamazsanız, burada listelenen diğer yöntemlerden birini kullanabilirsiniz: https://www.sqlite.org/tempfiles.html#temporary_file_storage_locations likePRAGMA temp_store_directory = 'directory-name';


2

Windows 7 altındaki IIS'den de aynı hatayı aldım. Bu hatayı düzeltmek için sqlite veritabanı dosyası için IUSR hesabına tam denetim izinleri eklemem gerekiyordu. IIS yerine webmatrix altında sqlite kullanırsanız izinleri değiştirmenize gerek yoktur.


2

Özetle, veritabanı dosyasını (* .db) bir alt klasöre koyarak sorunu çözdüm.

  • Alt klasör ve içindeki veritabanı dosyası, www-veri grubunun bir üyesi olmalıdır.
  • Www-data grubunda, alt klasöre ve veritabanı dosyasına yazma hakkına sahip olmalısınız.

0

Ben kullanmaktan değişince Tarayıcımdaki bu var http: // localhost için http://145.900.50.20 (145.900.50.20 benim yerel IP adresidir) ve daha sonra localhost için geri değişti - kalmak için gerekliydi IP adresini bir kez değiştirmiştim


0

Kullandım:

echo exec ('whoami');

betiği kimin çalıştırdığını bulmak için (örneğin kullanıcı adı) ve ardından kullanıcıya tüm uygulama dizinine aşağıdaki gibi izinler verin:

sudo chown -R: kullanıcı adı / var / www / html / uygulamam

Umarım bu dışarıdaki birine yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.