自制mysql的rpm包

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进行分发并安装,并提供不同的配置文件,这样还是很方便的
posted on 2017-08-28 19:18  wadeson  阅读(1130)  评论(0编辑  收藏  举报