2025-05-02 09:34:00
在Windows CMD中,如果无法直接cd
到一个网络目录(专门些的名字叫——通用命名约定〈UNC〉路径),可以使用net use
命令来临时挂载网络目录。以下是具体步骤12:
net use
命令挂载网络目录:net use Z: \\network_path\shared_folder /user:username password
Z:
是你希望分配给网络目录的本地驱动器号。\\network_path\shared_folder
是网络目录的路径。/user:username password
是访问网络目录所需的用户名和密码。Z: # 直接输入`Z:`便可切换至该挂载盘符
cd shared_folder # 然后用`cd`命令跳转
net use Z: /delete
pushd
命令在Windows CMD中,pushd
命令也可以用来临时挂载网络目录并切换到该目录(而且该方式还更常见一些)。具体步骤如下:
pushd
命令挂载网络目录3:set unc_path=\\network_path\shared_folder\b\c
pushd %unc_path%
popd
命令卸载网络目录:popd
使用pushd
命令时,它会将网络路径\\network_path\shared_folder
挂载到一个可用的盘符(例如Z:
),并将工作目录更改为Z:\b\c
。
但是,这种方法有一个致命的缺点:如果用户对\\network_path\shared_folder\b\c
有权限,但对\\network_path\shared_folder
没有权限,那么所有在此目录下的命令都会报错:Access is denied
4。
2024-11-05 10:16:45
如果容器正在使用docker-compose.yml
设置重启策略,临时将restart: always
改为restart: no
,然后执行docker-compose down
停止它。
手动启动容器并覆盖其默认命令,以便进入容器并设置权限。运行:
docker run -it --rm --entrypoint /bin/sh your_image_name
做完想做的事后,退出容器命令行:
exit
2024-10-12 12:01:44
在这篇博文中,笔者(山月)想记录自己如何解决BookWyrm部署过程中遇到的数据库问题,特别是在远程用户搜索时遇到的 “function similarity(character varying, unknown) does not exist” 错误。
背景是笔者(山月)从YunoHost搬迁到现有环境,使用Docker Compose来运行BookWyrm,但在搜索用户时总是出现数据库报错,提示找不到相似度函数。经过查找,了解到这是由于PostgreSQL中缺少pg_trgm
扩展导致的。
为了解决这个问题,笔者(山月)进入PostgreSQL数据库,并运行以下命令来安装所需的扩展:
CREATE EXTENSION IF NOT EXISTS pg_trgm;
执行上述命令后,数据库中添加了相应的相似度函数,错误终于得到了修复,用户搜索功能也正常运行了。
看来,有时候问题并不是代码本身,而是数据库的配置。
希望这篇文章能帮助到遇到类似问题的人,如果你也在使用BookWyrm或其他基于PostgreSQL的应用,记得检查是否已安装所有必要的扩展,尤其是像pg_trgm
这样的函数库,它能为用户搜索和文本相似度匹配提供很大的帮助。
2024-10-12 11:28:53
最近笔者(山月)将BookWyrm应用从YunoHost迁移到了使用Docker Compose的独立服务器环境,然而在新的环境中遇到了严重的问题:数据库中的表无法正常新增内容,例如无法添加图书、作者,或更新阅读状态等。在调试过程中,每次进行数据迁移操作时,都会遇到数据库主键重复的报错。这篇博文记录了笔者解决这一问题的全过程,希望能够帮助遇到相似困境的朋友们。
在将BookWyrm从YunoHost迁移到Docker Compose环境后,笔者(山月)发现新增数据的操作频繁失败,无论是添加图书、作者,还是更新阅读状态,都会遇到数据库报错的问题。具体表现为,当执行Django的migrate
命令时,报错显示主键重复(例如 django.db.utils.IntegrityError: duplicate key value violates unique constraint
)。
笔者最初的解决方案是手动调整有问题的数据库表的主键自增计数器。但由于涉及的表非常多,一个个手动调整非常低效。这个过程也让笔者意识到,数据库迁移中某些自增序列可能没有同步,导致插入新记录时主键重复。
在多次尝试手动解决主键问题无果后,笔者(山月)决定寻找一种更加自动化的方法,来确保所有数据库表的自增序列都能够同步。笔者最终找到了一个有效的方法:编写一个函数自动校准数据库中所有表的自增序列。
这个函数通过遍历数据库中所有具有自增序列的表,查询每个表的最大主键值,并将自增序列设置为该最大值加一。这样,所有表的自增序列都能够与表中现有数据保持一致,避免了重复主键错误。
下面是这个自动校准函数的实现:
-- 避免重复创建函数
DROP FUNCTION IF EXISTS reset_sequences_for_tables();
-- 重新创建函数
CREATE OR REPLACE FUNCTION reset_sequences_for_tables() RETURNS VOID AS $$
DECLARE
table_name_text TEXT;
seq_name TEXT;
max_id INT;
default_value TEXT;
pk_column_name TEXT;
BEGIN
FOR table_name_text IN
SELECT t.table_name
FROM information_schema.tables AS t
WHERE t.table_schema = 'public'
AND EXISTS (
SELECT 1
FROM information_schema.columns AS c
WHERE c.table_name = t.table_name
AND c.column_default ILIKE 'nextval%'
)
LOOP
SELECT column_name INTO pk_column_name
FROM information_schema.columns AS c
WHERE c.table_name = table_name_text
AND c.column_default ILIKE 'nextval%';
SELECT column_default INTO default_value
FROM information_schema.columns AS c
WHERE c.table_name = table_name_text
AND c.column_name = pk_column_name;
seq_name := substring(default_value from E'\'(\\w+)\'::regclass');
IF EXISTS (SELECT 1 FROM pg_class WHERE relname = seq_name) THEN
EXECUTE 'SELECT MAX(' || pk_column_name || ') FROM ' || table_name_text INTO max_id;
IF max_id IS NULL THEN
EXECUTE 'SELECT setval(' || quote_literal(seq_name) || ', 1, false)';
ELSE
EXECUTE 'SELECT setval(' || COALESCE(quote_literal(seq_name), 'null') || ', ' || max_id || ')';
END IF;
ELSE
RAISE NOTICE 'Sequence not found for table: %', table_name_text;
END IF;
END LOOP;
END;
$$ LANGUAGE plpgsql;
创建函数后,执行它来重置所有自增序列的值:
SELECT reset_sequences_for_tables();
这一步将自动校准所有有自增序列的表的主键序列,让它们与表中的最大ID对应,避免重复主键的情况。
执行该函数后,所有表的自增序列都得到了自动校准,数据库主键重复的问题也顺利解决了。执行migrate
命令不再报错,BookWyrm的功能恢复正常,现在可以正常添加图书、作者和更新阅读状态。
在迁移BookWyrm应用时,数据库中的自增序列可能因为不同的环境和数据迁移方式而失去同步,导致主键重复的问题。这篇博客记录了如何通过编写一个函数,自动校准PostgreSQL数据库中所有表的自增序列,确保数据一致性并解决问题。
如果你也遇到类似的问题,希望这篇文章能够对你有所帮助。
2024-05-04 22:47:30
好吧,我标题党了,非常地微信,非常地小红书。主要是刚刚处理完问题,心情难以平抑。
简单来说,如果您是QNAP NAS使用者,在用QNAP官方提供的MariaDB(如,MariaDB 10)时,千万不要将MariaDB的配置文件(.conf
)中,default-storage-engine
这一行的默认配置改为InnoDB
。
经常使用QTS的朋友都知道,QTS虽然是基于Linux设计的,但QNAP有对Linux进行魔改,乃至我们常用的一些软件,如Apache、MySQL等,也都做了自己的魔改。网上的很多文档里提供的/data
路径、.conf
路径等,在QTS下也是讨不着的。想在QTS找到这些路径,有以下两种思路:
/share/CACHEDEV1_DATA/.qpkg/
下面对应的程序目录里翻翻看——例如传说中的MySQL配置文件my.cnf
,在QTS下是/.../.qpkg/MariaDB10/etc/mariadb.conf
;/etc
、/var
之类的目录找找——不过在QTS的场合,多半是一些管道软连接,例如/etc/my.cnf
实际指向/mnt/HDA_ROOT/.config/my.cnf
;而迷惑人的是,该文件可能是别的MySQL实例的配置文件,而不是我们平常容易用到的QTS应用市场释出的MariaDB的配置文件。言归正传,MariaDB的配置文件(.conf
),即/.../.qpkg/MariaDB10/etc/mariadb.conf
,其中的default-storage-engine
这一行,默认配置为MyISAM
。据说,虽然MyISAM可以作为临时解决方案,但考虑到数据库的完整性和性能,长期来看最好能使InnoDB可用。从个人的业务需求出发,当时是想要改为InnoDB
了。
顺带一提,为了确认所有可用的存储引擎及其状态,可以使用这则sql命令:
SHOW ENGINES;
例如,我的场合,就收到如此输出:
+--------------------+---------+-------------------------------------------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+-------------------------------------------------------------------------------------------------+--------------+------+------------+
(从略)
| MyISAM | DEFAULT | Non-transactional engine with good performance and small data footprint | NO | NO | NO |
(从略)
| InnoDB | NO | Supports transactions, row-level locking, foreign keys and encryption for tables | NULL | NULL | NULL |
+--------------------+---------+-------------------------------------------------------------------------------------------------+--------------+------+------------+
8 rows in set (0.000 sec)
再次言归正传。所以要我就查找 default-storage-engine
这一行,将其更改为:
default-storage-engine = InnoDB
并确保没有任何行包含 skip-innodb
。如果有,需要将其注释掉(在行前加 #
)或删除。
然后增加InnoDB相关配置(可选),为了优化 InnoDB 的性能。在 [mysqld]
部分添加以下配置:
innodb_buffer_pool_size = 1G # 根据你服务器的内存大小调整
innodb_log_file_size = 256M
innodb_log_buffer_size = 32M
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
innodb_thread_concurrency = 8
修改配置文件后,需要重启数据库服务以使更改生效。一般能想到以下命令:
sudo systemctl restart mariadb.service
或者
sudo systemctl restart mysql.service
然而哪条在我的QTS都用不了。QTS图形界面下的AppCenter则不提供重启选项——这应该是为了数据稳定性考虑。于是我访问了QTS的shell界面,在App Management那边手动restart
了MariaDB。
注意,一旦你尝试start
或者restart
一款程序,就不要再发出或start
或restart
或stop
的指令了——直到你在图形界面确确实实看到系统消息栏显示该程序“已启动”(如果你的指令是restart
,那么你会先在系统消息栏看到“已停止”,过很久才会看到“已启动”,这时候才安全了),然后再去做你想要做的下一步指令。不要好像没有看到什么反应,就想要重复发出指令——在QTS下,这样会把数据搞坏。
按道理,如果数据库服务器重启成功,则需要验证InnoDB是否启用。重新连接到数据库,然后执行:
SHOW ENGINES;
检查 InnoDB 的状态是否为DEFAULT
或YES
。
我顺利重启了MariaDB,然而噩梦这才开始——从shell环境尝试访问mysql
,账号密码、什么的照常要求输入,但是输进去后就访问不进mysql命令行环境了。QTS的图形界面那边也打不开MariaDB 10——虽然软件状态显示为“已启动”。
我甚至重启了NAS,并再次尝试从shell、图形界面访问,仍然不行。一度以为是QTS restart一款程序会比较暴力,导致因进程被强行中断而数据坏掉。但又觉得官方提供的实践方式应该不至于不靠谱乃尔。出于试看看的心态找到MariaDB的配置文件(.conf
),将其中的default-storage-engine
这一行,改回默认配置,即MyISAM
。然后按前述方法从shell restart MariaDB 10。
一切恢复正常了。
作为结尾,所以,如果您是QNAP NAS使用者,在用QNAP官方提供的MariaDB(如,MariaDB 10)的时候,千万不要将MariaDB的配置文件(.conf
)中,default-storage-engine
这一行的默认配置改为InnoDB
。
2024-03-20 21:30:15
Wikibase是一组MediaWiki的扩展功能,用于在中央存储库中处理版本化数据。其主要组件包括:
Wikibase的核心功能是提供一个协作空间,供个人和团体以结构化的方式贡献、编辑和管理信息。它可以轻松地被计算机消费,翻译成多种语言,并作为链接开放数据网络的一部分与世界共享。
MediaWiki具备以.xml
格式导出内容的功能,结构化的Wikibase内容(属性、项目、词位)自然不例外。
但是,如果直接从[[Special:Import]]
页面上传.xml
,会被告知无法导入Wikibase内容。因为系统默认阻止这样的批量上传,避免Wikibase属性(P
后面的数字)、项目(Q
后面的数字)、词位(L
后面的数字)的唯一标识符冲突。
通过在MediaWiki服务器根目录的LocalSettings.php
中,加入一行这样的代码:
# 启用Wikibase项目的导入
$wgWBRepoSettings['allowEntityImport'] = true;
来取消限制。
但是这样导入之后,再想通过[[Special:NewItem]]
新建项目,却会被告知:
不可以建立一个新页面。 它已经存在。
这是因为想要新建的页面的唯一标识符与现存页面已有的唯一标识符冲突了。
——等等,可是我们在新建项目的时候,又没办法强行指定唯一标识符。难道是系统在不知道唯一标识符已经被占用的情况下,还想要指定该唯一标识符?
是的。
在MediaWiki所使用的数据库里,我们能看到这一数据表:
****_wb_id_counters
****
是实际设置的表头。每个人设的表头并不一样。在LocalSettings.php
中可以找到表头设定。例如笔者是这么设置的:
# MySQL具体设置
$wgDBprefix = "sanguok_";
那么我就会看到这样的数据表名:
sanguok_wb_id_counters
好的。那么在这一数据表中,有以下内容(以笔者情况为例):
id_type | id_value |
---|---|
77696B69626173652D6974656D | 6 |
在Wikibase的wb_id_counters
表中,id_type
和id_value
列用来追踪不同类型实体的ID计数。这里的77696B69626173652D6974656D
实际上是一个十六进制编码的字符串。当将这个十六进制字符串解码为ASCII文本时,它代表了某种类型的实体标识符。
让我们将77696B69626173652D6974656D
这串十六进制代码解码成ASCII文本来看看它表示什么:
hex_string = "77696B69626173652D6974656D"
ascii_string = bytes.fromhex(hex_string).decode('utf-8')
ascii_string
解码后,77696B69626173652D6974656D
代表的ASCII文本是wikibase-item
。这意味着在wb_id_counters
表中,这个条目是用来追踪Wikibase中“项目”(即item,例如Q1
、Q2
等)的最新ID计数的。在我的情况中,id_value
为6
,这表明追踪到的最新项目ID是Q6
。
然而,在我的实际情况里,经过批量导入后,Wikibase中最新的条目是item:Q10000
,这显然与wb_id_counters
表中的记录不匹配。
为了解决这个问题,需要根据实际的最新项目ID(在我的情况下是Q10000
),手动更新wb_id_counters
表中相应wikibase-item
类型的id_value
——例如在我的情况下,改为10000
。
之后,再试看看能否透过[[Special:NewItem]]
新建条目。
应该能够成功的。