From Amarok Wiki

Deutsch | English | Castellano | Italiano | Türkçe| 简体中文


Contents

配置 MySQL

Amarok 对 SMySQL 的支持

Amarok 1.2 及更高版本,除了内置的 SQLite 数据库引擎,还支持以 MySQL 作为数据库后台。为了能在编译后获得 MySQL 支持,你需要在编译的时候加上 " --enable-mysql "这个配置参数,然后再以 root 权限执行 " install ",你的配置行可能就像这样子:

$ ./configure --enable-mysql

还要请你确定你已经安装了 libmysqlclient 这个库文件和其头文件(是带着 -dev 字样的包)。

安装 MySQL

Amarok 1.4 需要 MySQL 版本在 4.0 及其以上,现在(撰写此文时) MySQL 的版本已经升到 5.0.22 了。Amarok-1.4.2 得 MySQL-5.0.24 以及 Amarok 1.4.5 和 MySQL 5.0.27 都融合的很好。

老版本的 Amarok 可能最好还是使用版本号 < 5.0 的MySQL。这是因为 Amarok 的数据库在不断增长,每个音轨在每次扫描时都要进行多次读取数据库。

如果你的 locale 是UTF-8,请确定你的 mqsl 守护程序的默认字符集也是设定为 utf8 的,这样所有创建的表和数据库的字符集都会是 utf8。在 Debian 中:

1) 编译Edit /etc/mysql/my.cnf, 在 之间添加这样一行:

default-character-set = utf8

2) 然后,重启 mqsql 守护程序,使新的默认字符集生效。

这些要在你为 amarok 创建数据库之前完成。

请确定 MySQL 守护程序正在运行当中。如果你必要,可以把它添加到你的 Linux 启动脚本中。方法请阅读你所用发行版的参考指南。

为 MySQL 创建一个 root 密码,如果你没有,就照下面这样做吧。

$ mysql -u root 
set password for root@localhost = password('xxxxxxx'); 
flush privileges; 
quit; 

当然要把 XXXXXX 改成你要设的密码。

这个做完后,你就要建立一个 MySQL 数据库 和一个 amarok 用户,方法自选。可以参考下面的 " mysql " 命令(会提醒你输入 MySQL root 的密码):

$ mysql -p -u root
CREATE DATABASE amarok;
USE amarok;
GRANT ALL ON amarok.* TO amarok@localhost IDENTIFIED BY 'PASSWORD_CHANGE_ME';
FLUSH PRIVILEGES;

在上面这个例子里,创建了一个名为 "amarok " 的数据库,得一个名为 " amarok "的用户。这个用户可以使用"PASSWORD_CHANGE_ME"这个密码来连接数据库。可以使用 amarokuser@'%' 来进行远程连接。

要用 'GRANT ALL' 把所权限都赋给 "amarok" 用户,这很重要,因为,"amarok" 用户需要 ALTER 权限来修改它的数据库。

数据库建好了之后,打开 Amarok 的配置界面(在设置(Settings)菜单中),点击收藏(Collection)标签。把下拉菜单的值 SQLite 换成 MySQL。同时,设定主机(host) "localhost&quot(如果数据库是在本机上), 端口号(一般都是3306), 你刚才新创建的数据库名("amarok&quot,或者你自己设定的名字)。另外 能对数据读写的用户还要填上密码(在本例中,用户名是 "amarok", 密码是 "PASSWORD_CHANGE_ME")

连接远程的 MySQL 服务器:绝大部分的 MySQL 守护程序都被默认设定为只侦听来自本机的请求。

因此,如果你在连接服务器或数据库出错时(不是密码错误),你可能要修改主机上的 my.cnf(一般路径是/etc/mmysql/my.cnf),注释掉"bind_address" 变量,然后重启 MySQL。如果是使用 tcp socket 来连接的话,可能还要注释掉 "skip_networking"。

现在还没有办法修改它侦听的接口。要么只侦听一个,要么全部。你最后可能要更新你的防火墙。

编辑

数据库转换

把 SQLite 数据库转成 MySQL 数据库

下面是一个把 SQLite 数据库转成 MySQL 数据库的方法(未经检验):

cd ~/.kde/share/apps/amarok && \
sqlite3 collection.db .dump | \ 
egrep -vi '^(BEGIN TRANSACTION|COMMIT|CREATE|INSERT INTO "devices")' | \
perl -pe 's/INSERT INTO \"(.*)\" VALUES/INSERT INTO \1 VALUES/' | \
mysql -u root -p amarok

有些人可能在使用以前的脚本时有些问题,但是现在上面这个版本没有了。如果,你在使用中出错了(专集名有反斜杠可能会导致错误),不要做最后一步,然后把结果输出到一个文件中。

cd ......\1 VALUES/' > ~/tmp/amarok_dump

使用你顺手的编辑器打开文件,修复错误。删除所有在 Amarok 数据库中生成的表格(编者使用的是phpMyAdmin,如果你想通过 MySQL 命令来完成,但是还不知道怎样做,就在这里查查吧the MySQL Reference Manual)!然后使用你生成的文件再试一下最后一句。

cat ~/tmp/amarok_dump | mysql -u root -p amarok

如果你遇到的错误像下面这样:

ERROR 1071 (42000) at line 25380: Specified key was too long; max key length is 1000 bytes

打开 amarok_dump 文件,把所有的 VARCHAR(1024) 替换成 VARCHAR(996)

原先的脚本试图提交下面的子句:

s/VARCHAR\(256\)/VARCHAR\(255\)/

但是,我的 SQLite dump 文件只支持到 VARCHAR(255)。你或许想要检查一下你的,运行下面的指令:

grep "VARCHAR(256)" ~/tmp/amarok_dump

如果出现什么错误,试着去修正它们:

perl -pe 's/VARCHAR\(256\)/VARCHAR\(255\)/' < ~/tmp/amarok_dump > ~/tmp/amarok_dump2 && mv ~/tmp/amarok_dump2 ~/tmp/amarok_dump

MySQL 自身默认也带有有用的命令行工具叫 replace,可以在一个文件中替换多个字符串:

replace "VARCHAR(256)" "VARCHAR(255)" -- ~/tmp/amarok_dump

你也可以在 search/replace 中使用成对的字符串,记住要以下面的结尾:

-- ~/tmp/amarok_dump

另外还有一个方法就是按照下面的操作导入 SQLite 数据:

  • 启动 Amarok, 转到 MySQL,然后构建数据库(但是千万不要播放什么音乐)
  • 下载 SQLite 数据库浏览器
  • 导出统计数据到一个 dump 文件,就叫 amarok_dump.sql 吧。
  • 删除所有的 BEGIN TRANSACTION, COMMIT 和 CREATE sql 命令
  • 最后使用 MySQL 导入这个文件:
cat amarok_dump.sql | mysql -u root -p amarok

如果出现了什么错误,十有八九可能是因为你在放歌,结果生成一个统计数据到你的文件中去了。如果是这样的话,你就要编辑 amarok_dump.sql 文件。找到那个导致出错的行,删除它前面所有的东西(因为这些命令都已经被 MySQL 执行过了-否则你还会出错)。如果你还想使用那个导致出错的行,把 INSERT INTO 都替换成 REPLACE INTO。然后,重新运行上面的命令。

把 MySQL 数据库转成 SQLite 数据库

下面是一个把 MySQL 数据库转成 SQLite3 数据库的方法(未经检验): (注意:这可能不能用在现在的 Amarok >= 1.4.2 版本上,因为模式(schema)发生了变化)

cd ~/.kde/share/apps/amarok && \
mv collection.db collection.db.old && \
mysqldump -uroot -p -n -t amarok | sed -e "s/\\\'/\'\'/g" | sed -e "s/\\\\\"/\"\"/g" > amarok.sql && \
sqlite3 collection.db

把下面的语句贴到你的 "sqlite>" 提示符里,就可以创建表格了:

CREATE TABLE album (id INTEGER PRIMARY KEY ,name VARCHAR(255) );
CREATE TABLE artist (id INTEGER PRIMARY KEY ,name VARCHAR(255) );
CREATE TABLE directories (dir VARCHAR(255) UNIQUE,changedate INTEGER );
CREATE TABLE genre (id INTEGER PRIMARY KEY ,name VARCHAR(255) );
CREATE TABLE images (path VARCHAR(255),artist VARCHAR(255),album VARCHAR(255) );
CREATE TABLE related_artists (artist VARCHAR(255),suggestion VARCHAR(255),changedate INTEGER );
CREATE TABLE statistics (url VARCHAR(255) UNIQUE,createdate INTEGER,accessdate INTEGER,percentage FLOAT,playcounter INTEGER,rating INTEGER);
CREATE TABLE tags (url VARCHAR(255),dir VARCHAR(255),createdate INTEGER,album INTEGER,artist INTEGER,genre INTEGER,title VARCHAR(255),year INTEGER,comment VARCHAR(255),track NUMERIC(4),bitrate INTEGER,length INTEGER,samplerate INTEGER,sampler BOOL );
CREATE TABLE year (id INTEGER PRIMARY KEY ,name VARCHAR(4) );
CREATE INDEX album_idx ON album( name );
CREATE INDEX album_tag ON tags( album );
CREATE INDEX artist_idx ON artist( name );
CREATE INDEX artist_tag ON tags( artist );
CREATE INDEX directories_dir ON directories( dir );
CREATE INDEX genre_idx ON genre( name );
CREATE INDEX genre_tag ON tags( genre );
CREATE INDEX images_album ON images( album );
CREATE INDEX images_artist ON images( artist );
CREATE INDEX percentage_stats ON statistics( percentage );
CREATE INDEX playcounter_stats ON statistics( playcounter );
CREATE INDEX related_artists_artist ON related_artists( artist );
CREATE INDEX sampler_tag ON tags( sampler );
CREATE INDEX url_stats ON statistics( url );
CREATE INDEX url_tag ON tags( url );
CREATE INDEX year_idx ON year( name );
CREATE INDEX year_tag ON tags( year );

然后,在你的 "sqlite>" 提示符后导入你的 mysqldump:

.read amarok.sql

针对 Amarok 1.4.8 和 MySQL 5.0.45

我打算把我在 Amarok 1.4.8 中使用的 MySQL 数据库转成 SQLite。我不能保证它会表现得很好,但对你或许有用,下面就是操作方法:

首先,备份原先的 SQLite 数据库,并导出 MySQL 数据库(带有一些转化)。

cd ~/.kde/share/apps/amarok && \
mv collection.db collection.db.old && \
mysqldump -u root --skip-opt --skip-comments -p -n -t amarok | grep -v magnatune_ | sed -e "s/\\\n/\n/g" | sed -e "s/\\\'/\'\'/g" | sed -e "s/\\\\\"/\"\"/g" > amarok.sql && \
sqlite3 collection.db

把下面的 SQL 语句贴到提示符下,来创建表和索引(我是通过导出由 Amarok 1.4.8 创建一个新的 SQLite 数据库模式(schema)来生成这个的)。

CREATE TABLE tags (url VARCHAR(1024),dir VARCHAR(1024),createdate INTEGER,modifydate INTEGER,album INTEGER,artist INTEGER,composer INTEGER,genre INTEGER,title VARCHAR(255),year INTEGER,comment TEXT,track NUMERIC(4),discnumber INTEGER,bitrate INTEGER,length INTEGER,samplerate INTEGER,filesize INTEGER,filetype INTEGER,sampler BOOL,bpm FLOAT,deviceid INTEGER);
CREATE TABLE album (id INTEGER PRIMARY KEY ,name VARCHAR(255));
CREATE TABLE artist (id INTEGER PRIMARY KEY ,name VARCHAR(255));
CREATE TABLE composer (id INTEGER PRIMARY KEY ,name VARCHAR(255));
CREATE TABLE genre (id INTEGER PRIMARY KEY ,name VARCHAR(255));
CREATE TABLE year (id INTEGER PRIMARY KEY ,name VARCHAR(255));
CREATE TABLE images (path VARCHAR(1024),deviceid INTEGER,artist VARCHAR(255),album VARCHAR(255));
CREATE TABLE embed (url VARCHAR(1024),deviceid INTEGER,hash VARCHAR(1024),description VARCHAR(255));
CREATE TABLE directories (dir VARCHAR(1024),deviceid INTEGER,changedate INTEGER);
CREATE TABLE uniqueid (url VARCHAR(1024),deviceid INTEGER,uniqueid VARCHAR(32) UNIQUE,dir VARCHAR(1024));
CREATE TABLE admin (noption VARCHAR(255), value VARCHAR(255));
CREATE TABLE related_artists (artist VARCHAR(255),suggestion VARCHAR(255),changedate INTEGER );
CREATE TABLE amazon ( asin VARCHAR(20), locale VARCHAR(2), filename VARCHAR(33), refetchdate INTEGER );
CREATE TABLE lyrics (url VARCHAR(1024), deviceid INTEGER,lyrics TEXT, uniqueid VARCHAR(32));
CREATE TABLE playlists (playlist VARCHAR(255), url VARCHAR(1024), tracknum INTEGER );
CREATE TABLE labels (id INTEGER PRIMARY KEY , name VARCHAR(255), type INTEGER);
CREATE TABLE tags_labels (deviceid INTEGER,url VARCHAR(1024), uniqueid VARCHAR(32), labelid INTEGER REFERENCES labels( id ) ON DELETE CASCADE );
CREATE TABLE podcastchannels (url VARCHAR(1024) UNIQUE,title VARCHAR(255),weblink VARCHAR(1024),image VARCHAR(1024),comment TEXT,copyright VARCHAR(255),parent INTEGER,directory VARCHAR(255),autoscan BOOL, fetchtype INTEGER, autotransfer BOOL, haspurge BOOL, purgecount INTEGER );
CREATE TABLE podcastepisodes (id INTEGER PRIMARY KEY , url VARCHAR(1024) UNIQUE,localurl VARCHAR(1024),parent VARCHAR(1024),guid VARCHAR(1024),title VARCHAR(255),subtitle VARCHAR(255),composer VARCHAR(255),comment TEXT,filetype VARCHAR(255),createdate VARCHAR(255),length INTEGER,size INTEGER,isNew BOOL );
CREATE TABLE podcastfolders (id INTEGER PRIMARY KEY , name VARCHAR(255),parent INTEGER, isOpen BOOL );
CREATE TABLE statistics (url VARCHAR(1024),deviceid INTEGER,createdate INTEGER,accessdate INTEGER,percentage FLOAT,rating INTEGER DEFAULT 0,playcounter INTEGER,uniqueid VARCHAR(32) UNIQUE,deleted BOOL DEFAULT 0,PRIMARY KEY(url, deviceid) );
CREATE TABLE devices (id INTEGER PRIMARY KEY ,type VARCHAR(255),label VARCHAR(255),lastmountpoint VARCHAR(255),uuid VARCHAR(255),servername VARCHAR(255),sharename VARCHAR(255));
CREATE INDEX album_idx ON album( name );
CREATE INDEX artist_idx ON artist( name );
CREATE INDEX composer_idx ON composer( name );
CREATE INDEX genre_idx ON genre( name );
CREATE INDEX year_idx ON year( name );
CREATE UNIQUE INDEX url_tag ON tags( url, deviceid );
CREATE INDEX album_tag ON tags( album );
CREATE INDEX artist_tag ON tags( artist );
CREATE INDEX composer_tag ON tags( composer );
CREATE INDEX genre_tag ON tags( genre );
CREATE INDEX year_tag ON tags( year );
CREATE INDEX sampler_tag ON tags( sampler );
CREATE INDEX images_album ON images( album );
CREATE INDEX images_artist ON images( artist );
CREATE INDEX images_url ON images( path, deviceid );
CREATE UNIQUE INDEX embed_url ON embed( url, deviceid );
CREATE INDEX embed_hash ON embed( hash );
CREATE UNIQUE INDEX directories_dir ON directories( dir, deviceid );
CREATE INDEX uniqueid_uniqueid ON uniqueid( uniqueid );
CREATE INDEX uniqueid_url ON uniqueid( url, deviceid );
CREATE INDEX tags_artist_index ON tags( artist );
CREATE INDEX tags_album_index ON tags( album );
CREATE INDEX tags_deviceid_index ON tags( deviceid );
CREATE INDEX tags_url_index ON tags( url );
CREATE INDEX embed_deviceid_index ON embed( deviceid );
CREATE INDEX embed_url_index ON embed( url );
CREATE INDEX related_artists_artist ON related_artists( artist );
CREATE INDEX url_podchannel ON podcastchannels( url );
CREATE INDEX url_podepisode ON podcastepisodes( url );
CREATE INDEX localurl_podepisode ON podcastepisodes( localurl );
CREATE INDEX url_podfolder ON podcastfolders( id );
CREATE INDEX devices_type ON devices( type );
CREATE INDEX devices_uuid ON devices( uuid );
CREATE INDEX devices_rshare ON devices( servername, sharename );
CREATE UNIQUE INDEX lyrics_url ON lyrics( url, deviceid );
CREATE INDEX lyrics_uniqueid ON lyrics( uniqueid );
CREATE INDEX playlist_playlists ON playlists( playlist );
CREATE INDEX url_playlists ON playlists( url );
CREATE UNIQUE INDEX labels_name ON labels( name, type );
CREATE INDEX tags_labels_uniqueid ON tags_labels( uniqueid );
CREATE INDEX tags_labels_url ON tags_labels( url, deviceid );
CREATE INDEX tags_labels_labelid ON tags_labels( labelid );
CREATE UNIQUE INDEX url_stats ON statistics( deviceid, url );
CREATE INDEX percentage_stats ON statistics( percentage );
CREATE INDEX rating_stats ON statistics( rating );
CREATE INDEX playcounter_stats ON statistics( playcounter );
CREATE INDEX uniqueid_stats ON statistics( uniqueid );

然后,导入从 MySQL 导出的实际数据。

.read amarok.sql
.quit

自动备份

注意:同时也有必要备份一下 ~/.kde/share/config/amarokrc,因为这个文件也包含一些重要的数据版本信息。

这个可以简单地使用 cron 任务来完成。 创建一个 Shell 脚本,放在你的 /etc/cron.weekly 目录下(或你自己的 cron 目录下)

 #!/bin/sh
 # Backup the Amarok MySQL database
 # Version 2007-02-06-b, 
 # now "/bin/sh -> /bin/dash" compatible; backup files now named "amarok.mysql.tar.bz2"; ask before overwrite
 

 ######### CHANGE SETTINGS HERE #########
 # Location to place Amarok-database backups:
 BACKUP_BASE_DIR=~/backup
 
 # Name of MySQL-database:
 AMAROKDB_NAME=amarok
 
 # Username and password for Amarok-MySQL-database:
 AMAROKDB_USER=amarok
 AMAROKDB_PW=PASSWORD
 
 # Location of amarokrc:
 AMAROKRC=~/.kde/share/config/amarokrc
 ######### END OF SETTINGS SECTION #########
 
 BACKUP_SUBDIRECTORY=`date +%Y-%m-%d`
 
 if [ ! -w $BACKUP_BASE_DIR -o ! -d $BACKUP_BASE_DIR ]
 then
   printf %b "\n\n $BACKUP_BASE_DIR doesn't exist or is not writable!\n\n"
   printf %b "STOP.\n\n"
   exit 1;
 fi
 
 if [ ! -r $AMAROKRC ]
 then
   printf %b "\n\n $AMAROKRC doesn't exist or Amarok is not installed!\n\n"
   printf %b "STOP.\n\n"
   exit 1;
 fi
 
 mkdir -p $BACKUP_BASE_DIR/amarok/$BACKUP_SUBDIRECTORY

                #using a temporary file in order not to overwrite an existing copy when the script is 
                #manually invoked a second time (e.g. right before restoration of existing backup of same date!)
 mysqldump -u $AMAROKDB_USER -p$AMAROKDB_PW $AMAROKDB_NAME -c -e --hex-blob > /tmp/amarok.mysql

 tar --remove-files -C /tmp -cvvjf /tmp/amarok.mysql.tar.bz2 amarok.mysql

 mv -i -v /tmp/amarok.mysql.tar.bz2 $BACKUP_BASE_DIR/amarok/$BACKUP_SUBDIRECTORY
 
 # The config file amarokrc will also be secured:
 cp -i -v $AMAROKRC $BACKUP_BASE_DIR/amarok/$BACKUP_SUBDIRECTORY
 

这个脚本将在 '~/backup/amarok' 创建一个由日期命名的目录,并把 MySQL dump 文件和'~/.kde/share/config/amarokrc' 配置文件打包以 bz2 压缩文件存储,这里假设用户名为 'amarok' 数据库名也为 'amarok' 。在这个设置中,要把"PASSWORD" 换成你自己的密码,如果名字不一样的话,也要换。同时,还需要你授(GRANT ALL)所有权限给 Amarok 用户。

重要:这个脚本不会备份你的播放列表。静态的.m3u 播放列表是存储在 ~/.kde/share/apps/amarok/playlists (你的 home 目录)(译者:在 amarok 2.0 中,静态列表是~/.kde/share/apps/amarok/playlistbrowser_save.xml) 。动态列表是存储在(译者:在 amarok 2.0 中,静态列表是~/.kde/share/apps/amarok/smartplaylistbrowser_save.xml).因为上面的脚本,没有备份它们,你需要手工拷贝到你所选择的备份目录下。

从一个自动备份中恢复

从一个先前备份中恢复只需要简单几步就可以了。 第一步,删除老的数据库并创建一个新的 amarok 数据库(本例使用和上面备份 脚本一样的命名):

# 这是新版本,先前的例子就不讨论了
# 所有权限都是通过 "GRANT ALL"... 操作的

$ mysql -p -u root
DROP DATABASE amarok;
CREATE DATABASE amarok;
USE mysql;
GRANT ALL ON amarok.* TO amarok@localhost IDENTIFIED BY 'PASSWORD_CHANGE_ME';
FLUSH PRIVILEGES;
QUIT;

第二步,我们需要恢复备份文件。我们假设这个备份文件是 2006 年 07 月 12 日生成的:

$ cd ~/backup/amarok/2006-07-12/
$ tar -xvjf amarok.mysql.tar.bz2
$ mysql -p -u amarok -h localhost amarok < amarok.mysql

现在你的数据库已经被恢复了。注意,第一步中的 'amarok'是用户名,第二步中的是数据库名。

注意:同时也有必要恢复一下 ~/.kde/share/config/amarokrc,因为这个文件也包含一些重要的数据版本信息。

修复一个受损的数据库

如果你的数据库被破坏了,你看不到你的收藏浏览器的所有格了,并且在 /var/log/messages 中发现你的 MySQL 数据库受到损坏。你可以在 root 权限下,使用 mysqlchenk 命令来修复:

mysqlcheck -p --auto-repair --all-databases

然后,重新扫描你的收藏来更新数据库。

关于分享 MySQL 数据库的提示

  • 最重要的是所有准备分享的机器,都要在相同的路径下有相同的音乐文件。同时要确定所有的 Amarok 都配置成扫描相同的目录。如果路径或目录不同,你的另一外不同的 Amarok 会一直不停地扫描收藏。
  • 确信你在准备分享数据库的所有机器上使用的是同一版本的 Amarok。
  • 在 Amarok 二进制程序中使用一个外部脚本来防止在音乐还没有装载,就开始数据库操作了(这可能会导致你的数据库被擦除掉)。
  • 通过只在一台机器上设置"监视文件夹变化(Watch folders for changes)"(在 Amarok 设置的收藏页)来限制更新增长。使用这个方法,当添加新音乐时,只有一台机器能把它扫到数据库中。另外,你也可以设置取消所有机器的增长扫描,通过手动扫描在需要的时候来更新你的收藏数据库(工具菜单->重新扫描收藏(Tools Menu, Rescan Collection))
  • 确保所有机器上的 Amarok 数据库设置是一样的,包括 name/username/password。

(你也可以在 Amarok 数据库上建立多个用户来实现)

  • 重要提示:在 Amarok 1.4.2 的动态收藏介绍中说,如果你想使用一个共享数据库,你需要在
    ~/.kde/share/config/amarokrc
    的[Collection] 段添加
    DynamicCollection=false

外部连接