Thay đổi chế độ cơ sở dữ liệu SQLite thành đọc-ghi


101

Làm cách nào để thay đổi cơ sở dữ liệu SQLite từ chỉ đọc sang đọc-ghi?

Khi tôi thực hiện câu lệnh cập nhật, tôi luôn nhận được:

Lỗi SQL: cố gắng viết cơ sở dữ liệu chỉ đọc

Tệp SQLite là một tệp có thể ghi trên hệ thống tệp.


3
Người dùng đang chạy sqlite3 (hoặc bất cứ thứ gì bạn đang sử dụng để thực hiện truy vấn) có quyền ghi vào db không? Bạn đã kiểm tra lại quyền sở hữu tệp chưa?
Tim Post

Tôi chắc rằng họ có quyền làm điều đó.
user143482

2
Tôi đã thấy điều này trong một ứng dụng web mà tôi đã quên đặt GID trên tệp cơ sở dữ liệu và tài khoản "www-data" (mà Apache chạy trong đó) đã bị từ chối quyền ghi vào tệp.
finnw

Câu trả lời:


86

Có thể có một số lý do cho thông báo lỗi này:

  • Một số quy trình có cơ sở dữ liệu mở cùng một lúc ( xem Câu hỏi thường gặp ).

  • Có một plugin để nén và mã hóa cơ sở dữ liệu. Nó không cho phép sửa đổi DB.

  • Cuối cùng, một Câu hỏi thường gặp khác nói: "Đảm bảo rằng thư mục chứa tệp cơ sở dữ liệu cũng có thể ghi được đối với người dùng thực thi tập lệnh CGI." Tôi nghĩ điều này là do công cụ cần tạo thêm tệp trong thư mục.

  • Toàn bộ hệ thống tệp có thể chỉ được đọc, chẳng hạn như sau khi gặp sự cố.

  • Trên hệ thống Unix, một quy trình khác có thể thay thế toàn bộ tệp.


26
Tôi đặt giá thầu của mình vào dấu đầu dòng thứ ba - thư mục chứa tệp DB cũng phải có thể ghi được để tệp khóa có thể được tạo.
Kimvais

Đầu tiên cho tôi: D
Vinay

Cái cuối cùng. Tôi luôn quên sudo: P
Storm

2
Tôi có thể thêm vào danh sách này: tệp cơ sở dữ liệu đã được thay thế trong quá trình sử dụng. Tôi không muốn phải giải thích sự ngu ngốc dẫn đến kết luận này.
Wim Rijnders

Đây nên được đánh dấu là câu trả lời. Trong trường hợp của tôi (Một ứng dụng dành cho máy tính để bàn), nó liên quan đến Windows Nén cơ sở dữ liệu do đĩa cứng chính có dung lượng quá thấp. Tôi nghĩ rằng các cửa sổ sẽ hỏi người dùng xem họ có muốn nén tệp để có được không gian hay không nếu người dùng nói có thì vấn đề cơ sở dữ liệu chỉ đọc có thể phát sinh.
Nandostyle

10

Tôi đã giải quyết vấn đề này bằng cách thay đổi chủ sở hữu từ người gốc thành tôi trên tất cả các tệp trên / db dir.

Chỉ cần thực hiện ls -ltrên thư mục đó, nếu bất kỳ bộ lọc nào thuộc sở hữu của rootbạn, chỉ cần thay đổi nó cho bạn, sử dụng:sudo chown user file


5

Lỗi này thường xảy ra khi cơ sở dữ liệu của bạn đã được một ứng dụng truy cập và bạn đang cố gắng truy cập nó bằng một ứng dụng khác.


Tại sao bạn lại cố gắng truy cập một cơ sở dữ liệu từ một cơ sở dữ liệu khác?
Peter Mortensen,

Tôi nghĩ anh ấy có nghĩa là từ một ứng dụng khác
amaurymartiny

4

Nếu sử dụng Android.

Đảm bảo rằng bạn đã thêm quyền để viết thư cho của EXTERNAL_STORAGEbạn AndroidManifest.xml.

Thêm dòng này vào AndroidManifest.xmltệp của bạn ở trên và bên ngoài <application>thẻ của bạn .

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Điều này sẽ cho phép ứng dụng của bạn ghi vào sdcard. Điều này sẽ hữu ích nếu của bạn EXTERNAL_STORAGElà nơi bạn đã lưu trữ cơ sở dữ liệu của mình trên thiết bị.


Điều này đã giải quyết vấn đề của tôi. Tôi đã sửa đổi câu hỏi để cung cấp chi tiết hơn và dễ đọc hơn.
prolink007 11/10/12

cảm ơn rất nhiều. nó cũng giải quyết được vấn đề của tôi. lên bỏ phiếu cho cho :)
Altaf Sami

4

Trong trình bao lệnh Linux, tôi đã làm:

chmod 777 <db_folder>

Nơi chứa tệp cơ sở dữ liệu.

Nó hoạt động. Bây giờ tôi có thể truy cập cơ sở dữ liệu của mình và thực hiện các truy vấn chèn.


Các tác động bảo mật là gì?
Peter Mortensen,

Điều này khác với câu trả lời của adrian như thế nào?
Peter Mortensen,

1
Nó hoạt động như giải pháp nhanh chóng nhưng cần phải đào trong cho bảo đảm tốt hơn giải pháp sau
troydo42

4
Điều này sẽ cấp tất cả các quyền cho tất cả người dùng, điều này có thể không phải là những gì bạn muốn từ quan điểm bảo mật.
Renel Chesak

3

(thông báo lỗi này thường gây hiểu lầm và thường là lỗi cấp phép chung)

Trên Windows

  • Nếu bạn đang phát hành SQL trực tiếp với cơ sở dữ liệu, hãy đảm bảo rằng bất kỳ ứng dụng nào bạn đang sử dụng để chạy SQL đang chạy với tư cách quản trị viên
  • Nếu một ứng dụng đang cố gắng cập nhật, tài khoản mà ứng dụng sử dụng để truy cập cơ sở dữ liệu có thể cần quyền trên thư mục chứa tệp cơ sở dữ liệu của bạn. Ví dụ: nếu IIS đang truy cập cơ sở dữ liệu, IUSR và IIS_IUSRS đều có thể cần các quyền thích hợp (bạn có thể thử điều này bằng cách tạm thời cấp cho các tài khoản này toàn quyền kiểm soát thư mục, kiểm tra xem điều này có hoạt động không, sau đó buộc các quyền lại nếu thích hợp)

1
Tôi đã phải chạy "Trình duyệt DB" với tư cách quản trị viên.
Eben Roux

1
Tôi đã cấp "toàn quyền kiểm soát" cho "Mọi người" trên Windows 10 và nó vẫn không hoạt động. Tuy nhiên, như @EbenRoux đã nêu, bạn cũng có thể cần chạy "Trình duyệt DB" với tư cách Quản trị viên, điều này đã làm cho nó hoạt động đối với tôi.
Peaceoutside

2

Tôi cũng gặp vấn đề này hôm nay.

Đó là do ActiveSync trên Windows Mobile - thư mục tôi đang làm việc đã được đồng bộ hóa nên quá trình AS lấy tệp DB thỉnh thoảng gây ra lỗi này.


1

Trên Linux, cấp quyền đọc / ghi cho toàn bộ thư mục chứa tệp cơ sở dữ liệu.

Ngoài ra, SELinux có thể đang chặn việc ghi. Bạn cần đặt các quyền chính xác.

Trong GUI quản lý SELinux của tôi (trên Fedora 19), tôi đã chọn hộp trên dòng có nhãn httpd_unified (Hợp nhất xử lý HTTPD của tất cả các tệp nội dung) và tôi đã sẵn sàng.


Quyền đọc / ghi cho ai?
Peter Mortensen,

Làm thế nào để kiểm tra và thiết lập điều đó?
SynCap

1

Để chia sẻ kinh nghiệm cá nhân tôi gặp phải với lỗi này mà cuối cùng đã khắc phục được cả hai. Có thể không nhất thiết phải liên quan đến vấn đề của bạn nhưng có vẻ như lỗi này chung chung đến mức có thể được quy cho hàng triệu thứ.

  1. Phiên bản cơ sở dữ liệu mở trong một ứng dụng khác. DB của tôi dường như đã ở trạng thái "bị khóa" nên nó chuyển sang chế độ chỉ đọc. Tôi đã có thể theo dõi nó bằng cách dừng phiên bản thứ 2 của ứng dụng chia sẻ DB.

  2. Quyền của cây thư mục - hãy đảm bảo tài khoản người dùng có quyền không chỉ ở cấp tệp mà còn ở toàn bộ cấp thư mục trên theo cách đến / cấp.

Cảm ơn


1

Trên Ubuntu, thay đổi chủ sở hữu thành nhóm Apache và cấp quyền phù hợp (không, không phải là 777):

sudo chgrp www-data <path to db.sqlite3>
sudo chmod 664 <path to db.sqlite3>

Cập nhật

Bạn cũng có thể đặt quyền cho nhómngười dùng .

sudo chown www-data:www-data <path to db.sqlite3>

4
Bạn vừa thay đổi nhóm , không phải người dùng (điều này tốt, và có lẽ tốt hơn là thay đổi người dùng, nhưng câu trả lời của bạn gây hiểu lầm).
Auspex

Điều gì khiến bạn nghĩ tệp phải thuộc về người dùng / nhóm Apache?
Murphy

0

Từ dòng lệnh, hãy nhập thư mục chứa tệp cơ sở dữ liệu của bạn và thực hiện lệnh sau:

chmod 777 databasefilename

Điều này sẽ cấp tất cả các quyền cho tất cả người dùng.


22
Đó là khá tệ.
Marco Kerwitz

câu trả lời hoàn hảo !
Jitesh Prajapati

Nó có thể giải quyết vấn đề này nhưng nó không được khuyến khích vì nó có thể dẫn đến vấn đề bảo mật.
kathir raja

0

Trên Windows:

tl; dr: Thử mở lại tệp.

Hệ thống của chúng tôi đang gặp sự cố này và chắc chắn không phải là vấn đề về quyền, vì bản thân chương trình sẽ có thể mở cơ sở dữ liệu dưới dạng có thể ghi từ nhiều luồng hầu hết thời gian, nhưng đôi khi (chỉ trên Windows, không phải trên OSX), một luồng sẽ gặp những lỗi này mặc dù tất cả các luồng khác trong chương trình không gặp khó khăn gì.

Cuối cùng chúng tôi phát hiện ra rằng các luồng bị lỗi chỉ là những luồng đang cố gắng mở cơ sở dữ liệu ngay lập tức sau khi một luồng khác đã đóng nó (trong vòng 3 ms). Chúng tôi suy đoán rằng vấn đề là do Windows (hoặc triển khai sqlite trong windows) không phải lúc nào cũng dọn dẹp tài nguyên tệp ngay lập tức khi đóng tệp. Chúng tôi đã giải quyết vấn đề này bằng cách chạy một truy vấn viết thử đối với db khi mở (ví dụ: tạo sau đó thả một bảng có tên ngớ ngẩn). Nếu tạo / thả không thành công, chúng tôi đợi 50 mili giây và thử lại, lặp lại cho đến khi thành công hoặc 5 giây trôi qua.

Nó đã làm việc; rõ ràng chỉ cần có đủ thời gian để tài nguyên được chuyển ra đĩa.


-1

Chỉnh sửa DB: Tôi đã gặp sự cố khi chỉnh sửa db. Tôi đã kết thúc việc phải
sudo chown 'tên người dùng không phải root' ts3server.sqlitedb
miễn là nó không phải là root, tôi có thể chỉnh sửa tệp. Tên người dùng là tên người dùng của tài khoản không phải gốc của tôi.

Tự động khởi động TeamSpeak: khi tài khoản không phải gốc của bạn
crontab -e
@reboot / đường dẫn đến ts3server / aka /home/ts3server/ts3server_startscript.sh start


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.