用户反馈在 Notebook 上无法创建 ipynb 文件,并且会返回以下的错误。
报错的信息是: Unexpected error while saving file: Untitled5.ipynb attempt to write a readonly database
这个是一个比较新的问题,因为团队之前也没有人遇见过,不过通过报错信息,很容易定位到这个 issue Creating Jupyter Notebook Failed: error to write a readonly database #5321。初步看,我们这里遇到的问题跟 issue 上是一样的。
虽然没有仔细看过 Jupyterhub 和 Jupyterlab 的代码,但是我们可以根据一些报错信息来进行进一步的排查。
[I 2024-01-18 09:48:31.909 SingleUserLabApp handlers:172] Creating new notebook in
[E 2024-01-18 09:48:31.910 SingleUserLabApp filemanager:449] Error while saving file: Untitled5.ipynb attempt to write a readonly database
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/jupyter_server/services/contents/filemanager.py", line 434, in save
self.check_and_sign(nb, path)
File "/usr/local/lib/python3.9/site-packages/jupyter_server/services/contents/manager.py", line 651, in check_and_sign
self.notary.sign(nb)
File "/usr/local/lib/python3.9/site-packages/nbformat/sign.py", line 462, in sign
self.store.store_signature(signature, self.algorithm)
File "/usr/local/lib/python3.9/site-packages/nbformat/sign.py", line 204, in store_signature
if not self.check_signature(digest, algorithm):
File "/usr/local/lib/python3.9/site-packages/nbformat/sign.py", line 239, in check_signature
self.db.execute(
sqlite3.OperationalError: attempt to write a readonly database
[W 2024-01-18 09:48:31.910 SingleUserLabApp web:1796] 500 POST /user/oscar01.liu/api/contents?1705542511901 (10.80.50.125): Unexpected error while saving file: Untitled5.ipynb attempt to write a readonly database
[W 2024-01-18 09:48:31.910 SingleUserLabApp handlers:649] Unexpected error while saving file: Untitled5.ipynb attempt to write a readonly database
[E 2024-01-18 09:48:31.911 SingleUserLabApp log:178] {
"Cookie": "jupyterhub-user-oscar01.liu=[secret]; _xsrf=[secret]; jupyterhub-user-oscar01.liu-oauth-state=[secret]",
"Accept-Language": "zh-CN,zh;q=0.9",
"Accept-Encoding": "gzip, deflate",
"Referer": "http://gd17-llm-002-jupyterhub.xxx.com/user/oscar01.liu/lab/workspaces/auto-P",
"Origin": "http://gd17-llm-002-jupyterhub.xxx.com",
"Accept": "*/*",
"Content-Type": "text/plain;charset=UTF-8",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Authorization": "token [secret]",
"X-Xsrftoken": "2|b9010b04|67edc801549f9be14554782ddb629233|1703062619",
"Content-Length": "29",
"X-Scheme": "http",
"X-Forwarded-Proto": "http,http",
"X-Forwarded-Port": "80,80",
"X-Forwarded-Host": "gd17-llm-002-jupyterhub.xxx.com",
"X-Forwarded-For": "10.80.50.125,10.122.196.115",
"X-Real-Ip": "10.80.50.125",
"X-Request-Id": "e6b76c0d4424e0f93a90fd0b10fc473b",
"Host": "gd17-llm-002-jupyterhub.xxx.com",
"Connection": "close"
}
当尝试创建 ipynb 文件的时候,Notebook 的容器会打出报错的日志,从日志上看,感觉就是创建 ipynb 的时候,Notebook 会有读写数据库这样的操作,结合 issue 和用户的行为,大概可以判断,是因为用户动了 $HOME/.local/share/jupyter
目录下的一些配置文件,而这个目录内,有一个 sqlite3 实现的内存数据库,会记录一些本地 Notebook 的信息,这个文件就是 nbsignatures.db,如下图。
我们可以通过 python 来打开这 db 文件,查看一下,具体有什么信息在里面,具体的代码如下。
import sqlite3
# 连接到 SQLite 数据库文件
conn = sqlite3.connect('$HOME/.local/share/jupyter/nbsignatures.db')
# 创建一个 cursor
cursor = conn.cursor()
# 查询 nbsignatures 表的所有数据
print("Data in nbsignatures table:")
cursor.execute("SELECT * FROM nbsignatures;")
for row in cursor.fetchall():
print(row)
# 关闭 cursor 和连接
cursor.close()
conn.close()
恢复的手段,要么是让用户把相关的文件和文件目录恢复,如果实在无法找回,最好的办法就是重启一下 Notebook 的容器了。