База данных для TeamCity содержит информацию о результатах и истории сборок, историю изменений в VCS, список и настройки build
-агентов, очередь сборок, аккаунты пользователей и их настройки.
Официальное руководство по TeamCity говорит однозначно:
> In short, do not EVER use internal HSQLDB database for production TeamCity instances.
Потому – выполним миграцию на MySQL.
Кроме того – мы хотим сохранить уже имеющиеся настройки.
На всякий случай – не забывайте делать полный бекап, подробности в статье TeamCity: резервное копирование сервера с помощью утилиты maintainDB.
Качаем драйвер подключения к серверу баз данных:
http://dev.mysql.com/downloads/connector/j/
Находим необходимый файл:
$ tar tf mysql-connector-java-5.1.27.tar.gz | grep "mysql-connector-java-5.1.27-bin.jar"
Извлекаем только его:
$ tar xf mysql-connector-java-5.1.27.tar.gz mysql-connector-java-5.1.27/mysql-connector-java-5.1.27-bin.jar
Копируем файл в каталог рабочий каталог сервера TeamCIty – .BuildServer/lib/jdbc/
:
$ cp mysql-connector-java-5.1.27/mysql-connector-java-5.1.27-bin.jar ../.BuildServer/lib/jdbc/
Переходим к настройке MySQL:
$ mysql -u root -p
Создаём базу данных:
mysql> create database teamcity_db1 default charset utf8;
Назначаем права:
mysql> grant all privileges on teamcity_db1.* to 'teamcity'@'localhost' identified by 'password';
Выходим из консоли mysql
-клиента, и переходим в каталог TeamCity:
$ cd ../.BuildServer/config/
Останавливаем сервер:
$ ./../../TeamCity/bin/runAll.sh stop Using CATALINA_BASE: ./.. Using CATALINA_HOME: ./.. Using CATALINA_TMPDIR: ./../temp Using JRE_HOME: /usr/java/jdk1.6.0_45/jre Using CLASSPATH: ./../bin/bootstrap.jar:./../bin/tomcat-juli.jar Stopping TeamCity build agent... Java executable is found in '/usr/java/jdk1.6.0_45/jre'. Starting TeamCity Build Agent Launcher... Agent home directory is /home/teamcity/TeamCity/buildAgent Received stop command from console. Sending agent shutdown command to: http://localhost:9090 Shutdown command successfully sent. Agent will exit when idle.
Проверим:
$ ps ux | grep teamcity
Копируем файл шаблона настроек подключения к серверу MySQL:
$ cp database.mysql.properties.dist database.properties
Редактируем его, указываем свои настройки:
connectionUrl=jdbc:mysql://localhost:3306/teamcity_db1 connectionProperties.user=teamcity connectionProperties.password=password
Запускаем сервер:
$ ./../../TeamCity/bin/runAll.sh start
Заходим на страницу сервера – и видим ошибку:
Could not connect to MySQL server.
SQL error when doing: Connecting to MySQL
SQL query: connect
SQL exception: Communications link failureThe last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Находим файл лога сервера:
$ find ~ -name "teamcity-server.log" /home/teamcity/TeamCity/logs/teamcity-server.log
$ tail /home/teamcity/TeamCity/logs/teamcity-server.log [2013-12-02 12:46:01,771] INFO - jetbrains.buildServer.STARTUP - Using external (MYSQL) database [2013-12-02 12:46:01,772] INFO - jetbrains.buildServer.STARTUP - Current stage: Connecting to the database [2013-12-02 12:46:03,159] ERROR - jetbrains.buildServer.STARTUP - Could not connect to MySQL server. SQL error when doing: Connecting to MySQL SQL query: connect SQL exception: Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. [2013-12-02 12:46:03,160] INFO - jetbrains.buildServer.STARTUP - Current stage: TeamCity server startup error [2013-12-02 12:46:03,160] INFO - jetbrains.buildServer.STARTUP - Administrator login is required from web UI using authentication token: 1789441316873297174
Останавливаем сервер:
$ ./../../TeamCity/bin/runAll.sh stop
Проверяем – есть ли доступ к базе у указанного пользователя:
$ mysql -u teamcity -p Enter password:
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | teamcity_db1 | +--------------------+
mysql> use teamcity_db1; Database changed mysql> show tables; Empty set (0.00 sec)
Есть.
Но проблема оказалось в другом – в настройках подключения TeamCIty указан адрес MySQL как localhost
, в то время как сам MySQL слушает адрес:
$ netstat -ln|grep 3306 tcp 0 0 10.***.***.239:3306 0.0.0.0:* LISTEN
Можно изменить настройки в файле конфигурации сервера MySQL:
# cat /etc/my.cnf | grep bind bind-address=10.***.***.239
А можно – в настройках подключения TeamCIty:
connectionUrl=jdbc:mysql://10.***.***.239:3306/teamcity_db1
Запускаем сервер:
$ ./../../TeamCity/bin/runAll.sh start
Опять ошибка:
TeamCity server startup error
Unexpected error during connecting to the database: Unexpected exception SQLException: SQL error when doing: Connecting to MySQL
SQL query: connect
SQL exception: null, message from server: “Host ‘thucydides’ is not allowed to connect to this MySQL server”
Т.к. мы подключаемся через внешний IP – то и права у пользователя должны быть с доступом с любого внешнего адреса.
Редактируем пользователя MySQL.
Смотрим текущие привилегии:
mysql> select host,user from user where user = "teamcity"; +-----------+----------+ | host | user | +-----------+----------+ | localhost | teamcity | +-----------+----------+ 1 row in set (0.01 sec)
Изменяем поле host
– вместо localhost
ставим %
– т.е. любой:
mysql> update user set host="%" where user="teamcity" and host="localhost"; Query OK, 1 row affected (0.01 sec)
mysql> select host,user from user where user = "teamcity"; +------+----------+ | host | user | +------+----------+ | % | teamcity | +------+----------+
mysql> flush privileges; Query OK, 0 rows affected (0.11 sec)
Запускаем сервер TeamCity:
$ ./../../TeamCity/bin/runAll.sh start
Теперь всё в порядке 🙂
Посмотрим лог:
$ tail /home/teamcity/TeamCity/logs/teamcity-server.log [2013-12-02 13:12:53,475] INFO - jetbrains.buildServer.STARTUP - Internal HSQL database file (/home/teamcity/.BuildServer/system/buildserver.data) exists, version: 2.2.9 [2013-12-02 13:12:53,531] INFO - jetbrains.buildServer.STARTUP - Database connection URL: jdbc:mysql://10.249.140.239:3306/teamcity_db1 [2013-12-02 13:12:53,531] INFO - jetbrains.buildServer.STARTUP - Using database connection URL from the database properties file. The URL is: jdbc:mysql://10.249.140.239:3306/teamcity_db1 [2013-12-02 13:12:53,531] INFO - jetbrains.buildServer.STARTUP - Using external (MYSQL) database [2013-12-02 13:12:53,531] INFO - jetbrains.buildServer.STARTUP - Current stage: Connecting to the database [2013-12-02 13:12:54,908] INFO - jetbrains.buildServer.STARTUP - Connected to the database successfully [2013-12-02 13:12:54,911] INFO - jetbrains.buildServer.STARTUP - Current stage: Checking the database [2013-12-02 13:12:55,091] INFO - jetbrains.buildServer.STARTUP - Database contains no tables. [2013-12-02 13:12:55,095] INFO - jetbrains.buildServer.STARTUP - Current stage: Database is empty or doesn't exist [2013-12-02 13:12:55,095] INFO - jetbrains.buildServer.STARTUP - Administrator login is required from web UI using authentication token: 9011271320520862873
НЕ нажимаем Proceed!
Можно зайти в панель управления, введя ключ из лог-файла – authentication token: 9011271320520862873
, но ничего особо ценного там нет – в файле лога информации больше.
Приступаем к миграции текущей базы данных HSQLDB в новую базу MySQL.
Важно:
The target database must be empty before the migration process (it must NOT contain any tables).
База должна быть полностью пустая.
Останавливаем TeamCity:
$ ./../../TeamCity/bin/runAll.sh stop
Копируем файл настроек подключения к MySQL (желательно, т.к. во время миграции оригинальный скрипт будет заменён):
$ cp database.properties database.MySQL.properties
И запускаем процесс миграции:
$ ./../../TeamCity/bin/maintainDB.sh migrate -S /home/teamcity/.BuildServer/config/database.hsqldb.properties.dist -T /home/teamcity/.BuildServer/config/database.MySQL.properties ... Finishing Restoring finished with warnings Changing default database connection in TeamCity configuration: Renaming old database.properties file to: database.properties.before.20131202.132229 Copying target database properties file from: /home/teamcity/.BuildServer/config/database.MySQL.properties to: /home/teamcity/.BuildServer/config/database.properties Done.
Тут ключи:
-S (source)
– исходный файл настроек подключения к базе данных. Т.к. ранее использовался HSQLDB – указываем его файл;
-T (target)
– файл настроек MySQL, в базу которого будет выполнена миграция данных.
О скрипте maintainDB.sh
можно почитать в той же статье – TeamCity: резервное копирование сервера с помощью утилиты maintainDB.
Стартуем сервер:
$ ./../../TeamCity/bin/runAll.sh start
Проверим процессы MySQL:
mysql> show full processlist; +---------+----------+------------------+--------------+---------+------+-------+-----------------------+ | Id | User | Host | db | Command | Time | State | Info | +---------+----------+------------------+--------------+---------+------+-------+-----------------------+ | 1671019 | teamcity | localhost | teamcity_db1 | Query | 0 | NULL | show full processlist | | 1671027 | teamcity | thucydides:14495 | teamcity_db1 | Sleep | 307 | | NULL | | 1671029 | teamcity | thucydides:14497 | teamcity_db1 | Sleep | 3 | | NULL | | 1671030 | teamcity | thucydides:14498 | teamcity_db1 | Sleep | 306 | | NULL | | 1671032 | teamcity | thucydides:14524 | teamcity_db1 | Sleep | 242 | | NULL | | 1671033 | teamcity | thucydides:14562 | teamcity_db1 | Sleep | 251 | | NULL | +---------+----------+------------------+--------------+---------+------+-------+-----------------------+
Готово.
После переключения на новую базу данных – сервер сообщит, что
110 tables in the MySQL database currently use MyISAM storage engine. To achieve better performance, switching to the InnoDB storage engine is recommended. For instructions on converting MyISAM tables to InnoDB, refer to the MySQL documentation. Make sure you read our recommendations for configuring MySQL.
Решение описано в статье MySQL: конвертация всех таблиц в базе данных из MyISAM в InnoDB.