自制mysql的rpm包

wadeson發表於2017-08-28

MySQL安裝一般使用RPM或者原始碼安裝的方式。
RPM安裝的優點是快速,方便.缺點是不能自定義安裝目錄.如果需要調整資料檔案和日誌檔案的存放位置,還需要進行一些手動調整。
原始碼安裝的優點是可以自定義安裝目錄,缺點是編譯時間長,過程複雜

其實還有一種方式,定製RPM包.
它相當於用原始碼安裝的方式定製了一個RPM包.一次打包,可以多次使用
它可以定製路徑,安裝時自動建立帳號,自動配置服務,環境變數等,並且安裝過程快速,簡單。
在大規模部署的場景下,優點十分突出.
缺點是製作RPM包,需要自己編寫Red Hat定義的spec檔案,而編寫完成後,也需要進行編譯

 

現在開始定製mysql的rpm包

1、定製rpm包,首先需要安裝一個包

  yum -y install rpm-build

2、定製rpm包只需要用到普通使用者便可以完成,所以這裡推薦使用普通使用者

  useradd wadeson

3、建立自制rpm包需要用到的基本倉庫目錄

  在使用者的家目錄下面執行[wadeson@testdb ~]$ rpmbuild ~,即可,會自動生成需要用到的一些目錄

  [wadeson@testdb rpmbuild]$ ll
  total 24
  drwxr-xr-x. 2 wadeson wadeson 4096 Aug 27 22:25 BUILD 解壓後的tar.gz
  drwxr-xr-x. 2 wadeson wadeson 4096 Aug 27 22:25 BUILDROOT 臨時安裝目錄,會打包該目錄下檔案
  drwxr-xr-x. 2 wadeson wadeson 4096 Aug 27 22:25 RPMS        編譯後存放的rpm檔案
  drwxr-xr-x. 2 wadeson wadeson 4096 Aug 27 22:25 SOURCES     原始碼和一些檔案的存放地
  drwxr-xr-x. 2 wadeson wadeson 4096 Aug 27 22:25 SPECS       編寫spec檔案vim 直接建立就有一部分樣例
  drwxr-xr-x. 2 wadeson wadeson 4096 Aug 27 22:25 SRPMS       src格式的rpm包存放的位置
 
這個工具打包的過程大致如下,
編寫spec指定打包的過程
將原始碼壓縮包放在SOURCES目錄下,
將原始碼解壓縮到BUILD目錄,執行make命令(mysql使用cmake,make)
將make install 的結果放在BUILDROOT目錄下,
最後將BUILDROOT下編譯好的二進位制檔案製作成RPM包。
並且可以指定在RPM安裝之前,安裝之後,解除安裝等過程執行的命令
 
目錄名 說明  macros中的巨集名
BUILD 編譯rpm包的臨時目錄%_builddir
BUILDROOT 編譯後生成的軟體臨時安裝目錄%_buildrootdir
RPMS 最終生成的可安裝rpm包的所在目錄%_rpmdir
SOURCES 所有原始碼和補丁檔案的存放目錄%_sourcedir
SPECS 存放SPEC檔案的目錄(重要)%_specdir
SRPMS 軟體最終的rpm原始碼格式存放路徑(暫時忽略掉,別掛在心上)%_srcrpmdir

相應的目錄建立好了之後,開始進行真正的操作,首先下載mysql的原始碼包,這裡以mysql-5.6.37為例

將下載好的mysql-5.6.37存放在相應的目錄:

[wadeson@testdb ~]$ cd rpmbuild/SOURCES/
[wadeson@testdb SOURCES]$ ll
total 31448
-rw-rw-r--. 1 wadeson wadeson 32200158 Aug 23 22:19 mysql-5.6.37.tar.gz

[wadeson@testdb rpmbuild]$ tree .
.
|-- BUILD
|-- BUILDROOT
|-- RPMS
|-- SOURCES
| `-- mysql-5.6.37.tar.gz
|-- SPECS
`-- SRPMS
 
一些巨集的引數:
[wadeson@testdb rpmbuild]$ rpmbuild --showrc|grep _topdir
-14: _builddir %{_topdir}/BUILD
-14: _buildrootdir %{_topdir}/BUILDROOT
-14: _rpmdir %{_topdir}/RPMS
-14: _sourcedir %{_topdir}/SOURCES
-14: _specdir %{_topdir}/SPECS
-14: _srcrpmdir %{_topdir}/SRPMS
-14: _topdir %{getenv:HOME}/rpmbuild
[wadeson@testdb rpmbuild]$ echo "%_topdir %(echo $HOME)/rpmbuild" > ~/.rpmmacros
[wadeson@testdb rpmbuild]$ rpmbuild --showrc|grep _topdir
-14: _builddir %{_topdir}/BUILD
-14: _buildrootdir %{_topdir}/BUILDROOT
-14: _rpmdir %{_topdir}/RPMS
-14: _sourcedir %{_topdir}/SOURCES
-14: _specdir %{_topdir}/SPECS
-14: _srcrpmdir %{_topdir}/SRPMS
-14: _topdir %(echo /home/wadeson)/rpmbuild
然後相應的巨集的值對應相應的目錄
 
理解好了這些之後,於是進入到SPEC目錄進行編寫spec檔案:
直接使用vim mysql.spec就可以,裡面預設帶有一些預設的配置,現在做如下修改,並配有相應的解釋:
 
Name: mysql                        後面可以變數引用:%{name}
Version: 5.6.37                     後面可以變數引用:%{version}
Release: 1%{?dist} {?dist}:                       ?表示後面的dist有值就啟用,沒有值就捨棄,dist根據系統版本來定義,像redhat5就是el5,redhat6就是el6
Summary: MySQL-5.6.37 RPM                      概要(隨便寫就行,不過就字元限制無需太長)
 
Group: applications/database                                   #需要在一個存在的組中,通過/usr/share/doc/rpm-version/GROUPS檢視完整的組列表
License: GPL
URL: http://www.mysql.com
Source0:            mysql-5.6.37.tar.gz                         因為這裡只用到了mysql原始碼,如果需要my.cnf配置檔案,那麼可以Source1:my.cnf依次類推
                 這個壓縮檔案需要放在指定的目錄中(/root/rpmbuild/SOURCES)
                 自動解壓的時候,會在這個指定目錄中找這個檔案
# prefix: /usr/local/mysql-5.6.37 當然這裡可以定義變數,下面使用%{prefix}進行引用
 
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root                            %{_tmppath}這個巨集的值可以通過上面rpmbuild --showrc|grep _tmppath檢視
                             #安裝或編譯時使用的虛擬目錄,在生成rpm的過程中,執行make install時就會把軟體安裝到該路徑中,預設構建根目錄為%{_topdir}/BUILDROOT
  [wadeson@testdb SPECS]$ rpmbuild --showrc|grep _tmppath
  -14: __dbi_other %{?_tmppath:tmpdir=%{_tmppath}} %{?__dbi_cdb}
  -14: _tmppath %{_var}/tmp
  [wadeson@testdb SPECS]$ rpmbuild --showrc|grep _var
  -14: _dbpath %{_var}/lib/rpm
  -14: _tmppath %{_var}/tmp
  -14: _var /var
  即%{_tmppath}真正的值為/var/tmp,
 
BuildRequires: cmake,ncurses-devel
    #在編譯過程中需要的包列表,以逗號分開,並可以指定最小版本。
#Requires:
 
AutoReqProv: no
 
 
%description
this is rpmbuilding mysql5.6.37 rpm
 
%define MYSQL_USER mysql                                   define進行定義變數
    # 1.如何定義變數?
    # %define author zuosi #定義了一個變數author,值為zuosi
%define MYSQL_GROUP mysql
 
%prep
%setup -q -n mysql-%{version}                          進行解壓-q不輸出資訊,-n指定解壓目錄
                              解壓原始碼包之後,會進入目錄執行build,它預設是根據%{name}和%{version}拼接的目錄.
 
 
%build                                         #該階段執行常見的configure和make操作
cmake . \
-DCMAKE_INSTALL_PREFIX:=/usr/local/mysql-5.6.37 \                    # 這裡的安裝的prefix可以定義變數取代,呼叫變數使用%{varname}就行
-DMYSQL_DATADIR=/data/mysql \
-DSYSCONFDIR=/etc \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DMYSQL_TCP_PORT=3306 \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci
 
make -j `cat /proc/cpuinfo | grep processor| wc -l`
                                 檢視計算機有幾個核,然後多執行緒編譯
# make %{?_smp_mflags}                   ← 多核則並行編譯,與上面選一個就行
 
 
%install
rm -rf %{buildroot}                          # 先刪掉之前的構建
make install DESTDIR=%{buildroot}                         # 安裝到哪裡
  然後執行%install
  將編譯之後的程式碼真實的安裝一遍,
  它安裝的目錄是/home/wadeson/rpmbuild/BUILDROOT/mysql-5.6.37-1.el6.x86_64/usr/local/mysql-5.6.37
  因為我們指定的安裝目錄是/usr/local/mysql-5.6.37,它相當於在一個沙盒中安裝了一遍.它會將沙盒中安裝之後的檔案打成RPM包
 
%clean
rm -rf %{buildroot}   # 清理構建倉庫中的BUILDROOT
 
%files   # 就是指定哪些沙盒中的檔案打入RPM包
%defattr(-, %{MYSQL_USER}, %{MYSQL_GROUP})
  #設定預設檔案許可權式%defattr(<file permissions>, <user>, <group>, <directory permissions>),-使用預設的許可權,文字檔案是0644,可執行檔案是0755
  #另外,defattr(檔案許可權,使用者名稱,組名,目錄許可權)用來指定許可權,如: %defattr(-,root,root,-),這條指令設定預設許可權。
%attr(755, %{MYSQL_USER}, %{MYSQL_GROUP}) /usr/local/mysql-5.6.37/*
  給basedir下的mysql賦許可權
 
 
%pre       # 是RPM安裝之前執行的命令這裡主要是建立資料檔案的目錄和帳號

mkdir -p /data/mysql
if ! id %{MYSQL_USER} > /dev/null 2>&1;then
  useradd -M -s /sbin/nologin %{MYSQL_USER}
fi
chown -R mysql:mysql /data/mysql

 
%post      # 是RPM安裝之後執行的命令這裡主要是建立資料庫例項,配置服務,配置環境變數

/usr/local/mysql-5.6.37/scripts/mysql_install_db --basedir=/usr/local/mysql-5.6.37 --datadir=/data/mysql --user=mysql
cp /usr/local/mysql-5.6.37/support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
chkconfig mysqld on
cp /usr/local/mysql-5.6.37/my.cnf /etc/my.cnf

 
%preun    # 是解除安裝RPM包執行的命令,主要用於清理
service mysqld stop
chkconfig --del mysqld
userdel mysql
rm -rf /home/mysql
rm -rf /data/mysql
rm -rf /etc/init.d/mysqld
rm -rf /usr/local/mysql-5.6.37
 
%changelog
下面是一個完整的spec檔案:
Name:   mysql
Version:    5.6.37
Release:        1%{?dist}
Summary:    MySQL-5.6.37 RPM

Group:  applications/database
License:    GPL
URL:    http://www.mysql.com
Source0:    mysql-5.6.37.tar.gz
BuildRoot:   %{_tmppath}/%{name}-%{version}-%{release}-root

BuildRequires:  cmake,ncurses-devel
#Requires:

AutoReqProv: no

%description
this is rpmbuilding mysql5.6.37 rpm

%define MYSQL_USER mysql
%define MYSQL_GROUP mysql

%prep
%setup -q -n mysql-%{version}


%build
cmake .                      \
-DCMAKE_INSTALL_PREFIX:=/usr/local/mysql-5.6.37 \
-DMYSQL_DATADIR=/data/mysql \
-DSYSCONFDIR=/etc \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DMYSQL_TCP_PORT=3306 \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci

make -j `cat /proc/cpuinfo | grep processor| wc -l`


%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}

%clean
rm -rf %{buildroot}

%files
%defattr(-, %{MYSQL_USER}, %{MYSQL_GROUP})
%attr(755, %{MYSQL_USER}, %{MYSQL_GROUP}) /usr/local/mysql-5.6.37/*

%pre
mkdir -p /data/mysql
if ! id %{MYSQL_USER} > /dev/null 2>&1;then
    useradd -M -s /sbin/nologin %{MYSQL_USER}
fi
chown -R mysql:mysql /data/mysql


%post
/usr/local/mysql-5.6.37/scripts/mysql_install_db --basedir=/usr/local/mysql-5.6.37 --datadir=/data/mysql --user=mysql
cp /usr/local/mysql-5.6.37/support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
chkconfig mysqld on
cp /usr/local/mysql-5.6.37/my.cnf /etc/my.cnf

%preun
service mysqld stop
chkconfig --del mysqld
userdel mysql
rm -rf /home/mysql
rm -rf /data/mysql
rm -rf /etc/init.d/mysqld
rm -rf /usr/local/mysql-5.6.37


%changelog


完成了spec檔案後,於是使用如下命令進行編譯:

[wadeson@testdb SPECS]$ rpmbuild --help
Usage: rpmbuild [OPTION...]
--quiet

Build options with [ <specfile> | <tarball> | <source package> ]:
-bp build through %prep (unpack sources and apply patches) from <specfile>
-bc build through %build (%prep, then compile) from <specfile>
-bi build through %install (%prep, %build, then install) from <specfile>
-bl verify %files section from <specfile>
-ba build source and binary packages from <specfile>
-bb build binary package only from <specfile>
-bs build source package only from <specfile>
-tp build through %prep (unpack sources and apply patches) from <tarball>
-tc build through %build (%prep, then compile) from <tarball>
-ti build through %install (%prep, %build, then install) from <tarball>
-ta build source and binary packages from <tarball>

$rpmbuild -bb mysql.spec

這裡會輸出相應的編譯過程,如遇到錯誤,可根據提示做相應修改

最終沒有錯誤的話,會在如下目錄生成rpm包:

[wadeson@testdb SPECS]$ ll ../RPMS/x86_64/mysql-5.6.37-1.el6.x86_64.rpm
-rw-rw-r--. 1 wadeson wadeson 53414300 Aug 27 23:48 ../RPMS/x86_64/mysql-5.6.37-1.el6.x86_64.rpm
 
在上述引數中,補充一些知識:
檢視整個rpm包的巨集變數
rpmbuild --showrc:顯示rpm所有的巨集
[wadeson@testdb SPECS]$ rpmbuild --showrc|grep _initddir               顯示單個巨集的值
-14: _initddir %{_sysconfdir}/rc.d/init.d
__rm /bin/rm:兩個下劃線後接命令,代表的就是當前系統本身的命令
 
得到相應的mysql的rpm包後,就可以進行ansible批量安裝了
[root@testdb ~]# yum install mysql-5.6.37-1.el6.x86_64.rpm    這個過程會在下面輸出mysql的初始化過程
 
接下來就可以檢視資料目錄,配置檔案以及basedir:
[root@testdb ~]# ll /data/mysql/
總用量 110604
-rw-rw----. 1 mysql mysql 12582912 8月 28 00:19 ibdata1
-rw-rw----. 1 mysql mysql 50331648 8月 28 00:19 ib_logfile0
-rw-rw----. 1 mysql mysql 50331648 8月 28 00:19 ib_logfile1
drwx------. 2 mysql mysql 4096 8月 28 00:19 mysql
drwx------. 2 mysql mysql 4096 8月 28 00:19 performance_schema
drwx------. 2 mysql mysql 4096 8月 28 00:19 test
配置檔案做相應的修改,就可以正常的啟動mysql了
 
定製rpm包:
定製RPM安裝包可以滿足大規模自動化部署的場景,將得到的rpm包通過ansible進行分發並安裝,並提供不同的配置檔案,這樣還是很方便的

相關文章