/
usr
/
bin
/
/usr/bin
mkdir
upload
Name
Size
Mode
Actions
aclocal
36478
0755
edit
dl
rm
aclocal-1.16
36478
0755
edit
dl
rm
addr2line
34224
0755
edit
dl
rm
agentxtrap
25128
0755
edit
dl
rm
animate
12128
0755
edit
dl
rm
ar
63448
0755
edit
dl
rm
arch
38232
0755
edit
dl
rm
arpaname
12104
0755
edit
dl
rm
as
911264
0755
edit
dl
rm
aspell
163328
0755
edit
dl
rm
at
1276
0755
edit
dl
rm
atq
1278
0755
edit
dl
rm
atrm
1280
0755
edit
dl
rm
autoconf
14768
0755
edit
dl
rm
autoheader
8534
0755
edit
dl
rm
autom4te
32181
0755
edit
dl
rm
automake
257949
0755
edit
dl
rm
automake-1.16
257949
0755
edit
dl
rm
autoreconf
21066
0755
edit
dl
rm
autoscan
17124
0755
edit
dl
rm
autoupdate
33872
0755
edit
dl
rm
awk
685848
0755
edit
dl
rm
b2sum
59072
0755
edit
dl
rm
base32
42464
0755
edit
dl
rm
base64
42488
0755
edit
dl
rm
basename
38312
0755
edit
dl
rm
bash
1154680
0755
edit
dl
rm
bashbug-64
7348
0755
edit
dl
rm
batch
137
0755
edit
dl
rm
bison
448224
0755
edit
dl
rm
bunzip2
37744
0755
edit
dl
rm
bzcat
37744
0755
edit
dl
rm
bzcmp
2128
0755
edit
dl
rm
bzdiff
2128
0755
edit
dl
rm
bzgrep
1677
0755
edit
dl
rm
bzip2
37744
0755
edit
dl
rm
bzip2recover
16832
0755
edit
dl
rm
bzless
1259
0755
edit
dl
rm
bzmore
1259
0755
edit
dl
rm
c++
1266616
0755
edit
dl
rm
c++filt
29584
0755
edit
dl
rm
c89
224
0755
edit
dl
rm
c99
215
0755
edit
dl
rm
cagefs_enter.proxied
1296
0755
edit
dl
rm
cal
67560
0755
edit
dl
rm
captoinfo
87360
0755
edit
dl
rm
cat
38360
0755
edit
dl
rm
catchsegv
3283
0755
edit
dl
rm
cc
1266576
0755
edit
dl
rm
chcon
72024
0755
edit
dl
rm
chgrp
67864
0755
edit
dl
rm
chmod
63688
0755
edit
dl
rm
chown
71976
0755
edit
dl
rm
chrt
38080
0755
edit
dl
rm
cksum
38288
0755
edit
dl
rm
cldetect
10593
0755
edit
dl
rm
clear
12840
0755
edit
dl
rm
cmp
106248
0755
edit
dl
rm
col
29704
0755
edit
dl
rm
colcrt
16872
0755
edit
dl
rm
colrm
25480
0755
edit
dl
rm
column
50656
0755
edit
dl
rm
comm
42560
0755
edit
dl
rm
compare
12136
0755
edit
dl
rm
composite
12120
0755
edit
dl
rm
conjure
12120
0755
edit
dl
rm
convert
12120
0755
edit
dl
rm
cp
151568
0755
edit
dl
rm
cpan
8370
0755
edit
dl
rm
cpp
1266552
0755
edit
dl
rm
crontab
1524
0755
edit
dl
rm
crontab.cagefs
55456
0755
edit
dl
rm
csplit
54968
0755
edit
dl
rm
curl
235600
0755
edit
dl
rm
cut
50704
0755
edit
dl
rm
date
108496
0755
edit
dl
rm
dbiprof
6206
0755
edit
dl
rm
dd
79840
0755
edit
dl
rm
delv
43480
0755
edit
dl
rm
df
93272
0755
edit
dl
rm
diff
274440
0755
edit
dl
rm
diff3
131688
0755
edit
dl
rm
dig
166072
0755
edit
dl
rm
dir
143256
0755
edit
dl
rm
dircolors
50744
0755
edit
dl
rm
dirname
34160
0755
edit
dl
rm
display
12128
0755
edit
dl
rm
dnstap-read
20920
0755
edit
dl
rm
du
109568
0755
edit
dl
rm
easy_install-3
-
0
edit
dl
rm
echo
38248
0755
edit
dl
rm
egrep
28
0755
edit
dl
rm
enc2xs
41958
0755
edit
dl
rm
enchant
21584
0755
edit
dl
rm
enchant-lsmod
13408
0755
edit
dl
rm
env
42344
0755
edit
dl
rm
eps2eps
639
0755
edit
dl
rm
eqn
237728
0755
edit
dl
rm
ex
1180352
0755
edit
dl
rm
expand
42592
0755
edit
dl
rm
expr
50760
0755
edit
dl
rm
factor
88032
0755
edit
dl
rm
false
34120
0755
edit
dl
rm
fc-cache
132
0755
edit
dl
rm
fc-cache-64
20840
0755
edit
dl
rm
fc-cat
16744
0755
edit
dl
rm
fc-conflist
12544
0755
edit
dl
rm
fc-list
12544
0755
edit
dl
rm
fc-match
16648
0755
edit
dl
rm
fc-pattern
12552
0755
edit
dl
rm
fc-query
12536
0755
edit
dl
rm
fc-scan
12552
0755
edit
dl
rm
fc-validate
16648
0755
edit
dl
rm
fgrep
28
0755
edit
dl
rm
file
25280
0755
edit
dl
rm
find
228632
0755
edit
dl
rm
flex
438728
0755
edit
dl
rm
flex++
438728
0755
edit
dl
rm
flock
33992
0755
edit
dl
rm
fmt
46584
0755
edit
dl
rm
fold
42408
0755
edit
dl
rm
free
21288
0755
edit
dl
rm
freetype-config
4416
0755
edit
dl
rm
funzip
37504
0755
edit
dl
rm
g++
1266616
0755
edit
dl
rm
gawk
685848
0755
edit
dl
rm
gcc
1266576
0755
edit
dl
rm
gcc-ar
37536
0755
edit
dl
rm
gcc-nm
37536
0755
edit
dl
rm
gcc-ranlib
37536
0755
edit
dl
rm
gcov
1377408
0755
edit
dl
rm
gcov-dump
584664
0755
edit
dl
rm
gcov-tool
622360
0755
edit
dl
rm
gencat
25432
0755
edit
dl
rm
geoiplookup
22416
0755
edit
dl
rm
geoiplookup6
22168
0755
edit
dl
rm
geqn
237728
0755
edit
dl
rm
GET
16217
0755
edit
dl
rm
getconf
33240
0755
edit
dl
rm
getent
33920
0755
edit
dl
rm
getopt
21024
0755
edit
dl
rm
ghostscript
12648
0755
edit
dl
rm
git
3845928
0755
edit
dl
rm
git-receive-pack
3845928
0755
edit
dl
rm
git-shell
2236688
0755
edit
dl
rm
git-upload-archive
3845928
0755
edit
dl
rm
git-upload-pack
3845928
0755
edit
dl
rm
gm
8024
0755
edit
dl
rm
gmake
240968
0755
edit
dl
rm
gneqn
908
0755
edit
dl
rm
gnroff
3312
0755
edit
dl
rm
gpg
1090344
0755
edit
dl
rm
gpg-agent
429360
0755
edit
dl
rm
gpg-error
34976
0755
edit
dl
rm
gpg-zip
3525
0755
edit
dl
rm
gpgsplit
89112
0755
edit
dl
rm
gpgv
462344
0755
edit
dl
rm
gpic
300896
0755
edit
dl
rm
gprof
105832
0755
edit
dl
rm
grep
198280
0755
edit
dl
rm
groff
127920
0755
edit
dl
rm
grops
195728
0755
edit
dl
rm
grotty
145304
0755
edit
dl
rm
groups
38288
0755
edit
dl
rm
gs
12648
0755
edit
dl
rm
gsnd
277
0755
edit
dl
rm
gsoelim
43576
0755
edit
dl
rm
gtar
459768
0755
edit
dl
rm
gtbl
158320
0755
edit
dl
rm
gtroff
824344
0755
edit
dl
rm
gunzip
2345
0755
edit
dl
rm
gzexe
6375
0755
edit
dl
rm
gzip
96944
0755
edit
dl
rm
h2ph
29382
0755
edit
dl
rm
h2xs
60866
0755
edit
dl
rm
head
46592
0755
edit
dl
rm
hexdump
58888
0755
edit
dl
rm
host
145704
0755
edit
dl
rm
hostid
34136
0755
edit
dl
rm
hostname
21664
0755
edit
dl
rm
hunspell
148168
0755
edit
dl
rm
iconv
62904
0755
edit
dl
rm
id
46528
0755
edit
dl
rm
identify
12128
0755
edit
dl
rm
idn
40352
0755
edit
dl
rm
ifnames
4128
0755
edit
dl
rm
import
12120
0755
edit
dl
rm
infocmp
62512
0755
edit
dl
rm
infotocap
87360
0755
edit
dl
rm
install
159912
0755
edit
dl
rm
instmodsh
4194
0755
edit
dl
rm
ionice
29680
0755
edit
dl
rm
ipcrm
29688
0755
edit
dl
rm
ipcs
54680
0755
edit
dl
rm
isosize
25480
0755
edit
dl
rm
ispell
988
0755
edit
dl
rm
join
54984
0755
edit
dl
rm
kill
38176
0755
edit
dl
rm
ld
1789080
0755
edit
dl
rm
ld.bfd
1789080
0755
edit
dl
rm
ldd
5441
0755
edit
dl
rm
less
177928
0755
edit
dl
rm
lessecho
12696
0755
edit
dl
rm
lesskey
22520
0755
edit
dl
rm
lesspipe.sh
3143
0755
edit
dl
rm
lex
438728
0755
edit
dl
rm
libnetcfg
15775
0755
edit
dl
rm
libtool
367724
0755
edit
dl
rm
libtoolize
129197
0755
edit
dl
rm
link
34136
0755
edit
dl
rm
ln
72192
0755
edit
dl
rm
locale
57800
0755
edit
dl
rm
localedef
314848
0755
edit
dl
rm
logger
51184
0755
edit
dl
rm
login
41944
0755
edit
dl
rm
logname
34144
0755
edit
dl
rm
look
16856
0755
edit
dl
rm
ls
143248
0755
edit
dl
rm
m4
190016
0755
edit
dl
rm
Magick-config
1460
0755
edit
dl
rm
MagickCore-config
1596
0755
edit
dl
rm
MagickWand-config
1597
0755
edit
dl
rm
Mail
418704
0755
edit
dl
rm
mail
418704
0755
edit
dl
rm
mailx
418704
0755
edit
dl
rm
make
240968
0755
edit
dl
rm
make-dummy-cert
610
0755
edit
dl
rm
mariadb
5586328
0755
edit
dl
rm
mariadb-access
111961
0755
edit
dl
rm
mariadb-admin
5111488
0755
edit
dl
rm
mariadb-binlog
5413112
0755
edit
dl
rm
mariadb-check
5104544
0755
edit
dl
rm
mariadb-conv
4800544
0755
edit
dl
rm
mariadb-convert-table-format
4221
0755
edit
dl
rm
mariadb-dump
5200936
0755
edit
dl
rm
mariadb-dumpslow
8242
0755
edit
dl
rm
mariadb-embedded
25435072
0755
edit
dl
rm
mariadb-find-rows
3290
0755
edit
dl
rm
mariadb-hotcopy
35359
0755
edit
dl
rm
mariadb-import
5095200
0755
edit
dl
rm
mariadb-plugin
4779408
0755
edit
dl
rm
mariadb-secure-installation
13799
0755
edit
dl
rm
mariadb-setpermission
17977
0755
edit
dl
rm
mariadb-show
5093680
0755
edit
dl
rm
mariadb-slap
5113168
0755
edit
dl
rm
mariadb-tzinfo-to-sql
4778792
0755
edit
dl
rm
mariadb-waitpid
4766200
0755
edit
dl
rm
mc
1360320
0755
edit
dl
rm
mcdiff
1360320
0755
edit
dl
rm
mcedit
1360320
0755
edit
dl
rm
mcookie
34064
0755
edit
dl
rm
mcview
1360320
0755
edit
dl
rm
md5sum
46632
0755
edit
dl
rm
mesg
16752
0755
edit
dl
rm
mkdir
84680
0755
edit
dl
rm
mkfifo
68056
0755
edit
dl
rm
mknod
72160
0755
edit
dl
rm
mktemp
46760
0755
edit
dl
rm
mogrify
12120
0755
edit
dl
rm
montage
12120
0755
edit
dl
rm
more
46016
0755
edit
dl
rm
msql2mysql
1446
0755
edit
dl
rm
mv
147408
0755
edit
dl
rm
mysql
5586328
0755
edit
dl
rm
mysqlaccess
111961
0755
edit
dl
rm
mysqladmin
5111488
0755
edit
dl
rm
mysqlbinlog
5413112
0755
edit
dl
rm
mysqlcheck
5104544
0755
edit
dl
rm
mysqldump
5200936
0755
edit
dl
rm
mysqlimport
5095200
0755
edit
dl
rm
mysqlshow
5093680
0755
edit
dl
rm
mysql_config
4623
0755
edit
dl
rm
mysql_find_rows
3290
0755
edit
dl
rm
mysql_waitpid
4766200
0755
edit
dl
rm
mytop
73757
0755
edit
dl
rm
my_print_defaults
4770672
0755
edit
dl
rm
namei
33896
0755
edit
dl
rm
nano
253888
0755
edit
dl
rm
neqn
908
0755
edit
dl
rm
net-snmp-create-v3-user
3223
0755
edit
dl
rm
nice
38224
0755
edit
dl
rm
nl
46648
0755
edit
dl
rm
nm
51584
0755
edit
dl
rm
nohup
38312
0755
edit
dl
rm
nproc
38304
0755
edit
dl
rm
nroff
3312
0755
edit
dl
rm
nslookup
149768
0755
edit
dl
rm
nsupdate
74808
0755
edit
dl
rm
numfmt
67216
0755
edit
dl
rm
objcopy
245832
0755
edit
dl
rm
objdump
429832
0755
edit
dl
rm
od
75576
0755
edit
dl
rm
openssl
763856
0755
edit
dl
rm
pango-list
12160
0755
edit
dl
rm
pango-view
58816
0755
edit
dl
rm
passwd
1284
0755
edit
dl
rm
paste
38280
0755
edit
dl
rm
patch
211416
0755
edit
dl
rm
pathchk
38224
0755
edit
dl
rm
pdf2dsc
698
0755
edit
dl
rm
pdf2ps
909
0755
edit
dl
rm
perl
12728
0755
edit
dl
rm
perl5.26.3
12728
0755
edit
dl
rm
perlbug
45458
0755
edit
dl
rm
perldoc
118
0755
edit
dl
rm
perlivp
10813
0755
edit
dl
rm
perlml
6768
0755
edit
dl
rm
perlthanks
45458
0755
edit
dl
rm
pgrep
29536
0755
edit
dl
rm
php
937
0755
edit
dl
rm
pic
300896
0755
edit
dl
rm
piconv
8271
0755
edit
dl
rm
pinentry
2404
0755
edit
dl
rm
pinentry-curses
79760
0755
edit
dl
rm
ping
67712
0755
edit
dl
rm
pinky
42456
0755
edit
dl
rm
pip-3
-
0
edit
dl
rm
pip3
-
0
edit
dl
rm
pkg-config
41000
0755
edit
dl
rm
pkgconf
41000
0755
edit
dl
rm
pkill
29536
0755
edit
dl
rm
pl2pm
4533
0755
edit
dl
rm
pmap
33568
0755
edit
dl
rm
pod2html
4134
0755
edit
dl
rm
pod2man
15034
0755
edit
dl
rm
pod2text
10803
0755
edit
dl
rm
pod2usage
3948
0755
edit
dl
rm
podchecker
3658
0755
edit
dl
rm
podselect
2527
0755
edit
dl
rm
post-grohtml
244456
0755
edit
dl
rm
pr
84120
0755
edit
dl
rm
pre-grohtml
133688
0755
edit
dl
rm
precat
5656
0755
edit
dl
rm
preunzip
5656
0755
edit
dl
rm
prezip
5656
0755
edit
dl
rm
prezip-bin
12264
0755
edit
dl
rm
printenv
34120
0755
edit
dl
rm
printf
54848
0755
edit
dl
rm
prove
13562
0755
edit
dl
rm
ps
137984
0755
edit
dl
rm
ps2ascii
631
0755
edit
dl
rm
ps2epsi
2752
0755
edit
dl
rm
ps2pdf
272
0755
edit
dl
rm
ps2pdf12
215
0755
edit
dl
rm
ps2pdf13
215
0755
edit
dl
rm
ps2pdf14
215
0755
edit
dl
rm
ps2pdfwr
1097
0755
edit
dl
rm
ps2ps
647
0755
edit
dl
rm
ps2ps2
669
0755
edit
dl
rm
ptx
79864
0755
edit
dl
rm
pwd
38320
0755
edit
dl
rm
pwdx
12984
0755
edit
dl
rm
pydoc-3
-
0
edit
dl
rm
pydoc3
-
0
edit
dl
rm
python2
8032
0755
edit
dl
rm
python2.7
8032
0755
edit
dl
rm
python3
11872
0755
edit
dl
rm
python3.6
11872
0755
edit
dl
rm
python3.6m
11872
0755
edit
dl
rm
pyvenv-3
-
0
edit
dl
rm
ranlib
63456
0755
edit
dl
rm
raw
16896
0755
edit
dl
rm
readelf
639528
0755
edit
dl
rm
readlink
46984
0755
edit
dl
rm
realpath
51144
0755
edit
dl
rm
recode
48160
0755
edit
dl
rm
rename
16896
0755
edit
dl
rm
renew-dummy-cert
725
0755
edit
dl
rm
renice
16856
0755
edit
dl
rm
replace
4748656
0755
edit
dl
rm
reset
25352
0755
edit
dl
rm
rev
12760
0755
edit
dl
rm
rm
72064
0755
edit
dl
rm
rmdir
46552
0755
edit
dl
rm
rnano
253888
0755
edit
dl
rm
run-with-aspell
85
0755
edit
dl
rm
runcon
38264
0755
edit
dl
rm
rvi
1180352
0755
edit
dl
rm
rview
1180352
0755
edit
dl
rm
rvim
3067744
0755
edit
dl
rm
scalar
2290912
0755
edit
dl
rm
scl
37752
0755
edit
dl
rm
scl_enabled
258
0755
edit
dl
rm
scl_source
1863
0755
edit
dl
rm
scp
105304
0755
edit
dl
rm
script
37680
0755
edit
dl
rm
sdiff
107856
0755
edit
dl
rm
sed
118248
0755
edit
dl
rm
selectorctl
7812
0755
edit
dl
rm
seq
54728
0755
edit
dl
rm
setsid
16768
0755
edit
dl
rm
setterm
46208
0755
edit
dl
rm
sftp
163576
0755
edit
dl
rm
sh
1154680
0755
edit
dl
rm
sha1sum
46640
0755
edit
dl
rm
sha224sum
46672
0755
edit
dl
rm
sha256sum
46680
0755
edit
dl
rm
sha384sum
46688
0755
edit
dl
rm
sha512sum
46680
0755
edit
dl
rm
shred
63336
0755
edit
dl
rm
shuf
59488
0755
edit
dl
rm
size
34048
0755
edit
dl
rm
skill
29488
0755
edit
dl
rm
slabtop
21344
0755
edit
dl
rm
sleep
38288
0755
edit
dl
rm
snice
29488
0755
edit
dl
rm
snmpconf
26051
0755
edit
dl
rm
soelim
43576
0755
edit
dl
rm
sort
126432
0755
edit
dl
rm
spell
122
0755
edit
dl
rm
splain
19150
0755
edit
dl
rm
split
59440
0755
edit
dl
rm
sprof
29360
0755
edit
dl
rm
sqlite3
1346512
0755
edit
dl
rm
ssh
775648
0755
edit
dl
rm
ssh-add
354416
0755
edit
dl
rm
ssh-agent
333400
0755
edit
dl
rm
ssh-copy-id
10694
0755
edit
dl
rm
ssh-keygen
437424
0755
edit
dl
rm
ssh-keyscan
438800
0755
edit
dl
rm
stat
88232
0755
edit
dl
rm
stdbuf
50688
0755
edit
dl
rm
strace
2029832
0755
edit
dl
rm
stream
12112
0755
edit
dl
rm
strings
38328
0755
edit
dl
rm
strip
245856
0755
edit
dl
rm
stty
79472
0755
edit
dl
rm
sum
46624
0755
edit
dl
rm
sync
38256
0755
edit
dl
rm
tabs
16952
0755
edit
dl
rm
tac
42488
0755
edit
dl
rm
tail
75912
0755
edit
dl
rm
tar
459768
0755
edit
dl
rm
taskset
38152
0755
edit
dl
rm
tbl
158320
0755
edit
dl
rm
tclsh
9256
0755
edit
dl
rm
tclsh8.6
9256
0755
edit
dl
rm
tee
42472
0755
edit
dl
rm
test
54848
0755
edit
dl
rm
tic
87360
0755
edit
dl
rm
timeout
42864
0755
edit
dl
rm
tload
17160
0755
edit
dl
rm
tmpwatch
36320
0755
edit
dl
rm
toe
16848
0755
edit
dl
rm
top
124616
0755
edit
dl
rm
touch
96192
0755
edit
dl
rm
tput
25392
0755
edit
dl
rm
tr
50816
0755
edit
dl
rm
troff
824344
0755
edit
dl
rm
true
34128
0755
edit
dl
rm
truncate
42352
0755
edit
dl
rm
tset
25352
0755
edit
dl
rm
tsort
42488
0755
edit
dl
rm
tty
34112
0755
edit
dl
rm
tzselect
15370
0755
edit
dl
rm
uapi
1280
0755
edit
dl
rm
ul
21080
0755
edit
dl
rm
uname
38224
0755
edit
dl
rm
unexpand
46704
0755
edit
dl
rm
uniq
50832
0755
edit
dl
rm
unlink
34144
0755
edit
dl
rm
unversioned-python
-
0
edit
dl
rm
unzip
206728
0755
edit
dl
rm
unzipsfx
103912
0755
edit
dl
rm
uptime
12888
0755
edit
dl
rm
users
38288
0755
edit
dl
rm
utmpdump
29352
0755
edit
dl
rm
vdir
143256
0755
edit
dl
rm
vi
1180352
0755
edit
dl
rm
view
1180352
0755
edit
dl
rm
vim
3067744
0755
edit
dl
rm
vimdiff
3067744
0755
edit
dl
rm
vimtutor
2121
0755
edit
dl
rm
vmstat
37672
0755
edit
dl
rm
Wand-config
1455
0755
edit
dl
rm
watch
29888
0755
edit
dl
rm
wc
50832
0755
edit
dl
rm
wget
533928
0755
edit
dl
rm
whereis
29976
0755
edit
dl
rm
which
30088
0755
edit
dl
rm
who
54880
0755
edit
dl
rm
whoami
34136
0755
edit
dl
rm
word-list-compress
12280
0755
edit
dl
rm
x86_64-redhat-linux-c++
1266616
0755
edit
dl
rm
x86_64-redhat-linux-g++
1266616
0755
edit
dl
rm
x86_64-redhat-linux-gcc
1266576
0755
edit
dl
rm
x86_64-redhat-linux-gcc-8
1266576
0755
edit
dl
rm
xargs
75888
0755
edit
dl
rm
xmlcatalog
20864
0755
edit
dl
rm
xmllint
75128
0755
edit
dl
rm
xmlwf
37848
0755
edit
dl
rm
xsltproc
29152
0755
edit
dl
rm
xsubpp
5080
0755
edit
dl
rm
xxd
21032
0755
edit
dl
rm
yes
34168
0755
edit
dl
rm
zcat
1983
0755
edit
dl
rm
zcmp
1677
0755
edit
dl
rm
zdiff
5879
0755
edit
dl
rm
zegrep
29
0755
edit
dl
rm
zfgrep
29
0755
edit
dl
rm
zforce
2080
0755
edit
dl
rm
zgrep
7582
0755
edit
dl
rm
zip
234496
0755
edit
dl
rm
zipcloak
105376
0755
edit
dl
rm
zipgrep
2953
0755
edit
dl
rm
zipinfo
206728
0755
edit
dl
rm
zipnote
100104
0755
edit
dl
rm
zipsplit
100104
0755
edit
dl
rm
zless
2205
0755
edit
dl
rm
zmore
1841
0755
edit
dl
rm
znew
4552
0755
edit
dl
rm
zsoelim
43576
0755
edit
dl
rm
[
54864
0755
edit
dl
rm
Edit:
/usr/bin/mariadb-hotcopy
(35359B)
#!/usr/bin/perl # Copyright (c) 2000, 2017, Oracle and/or its affiliates. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; version 2 # of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, # MA 02110-1335 USA use strict; use Getopt::Long; use Data::Dumper; use File::Basename; use File::Path; use DBI; use Sys::Hostname; use File::Copy; use File::Temp qw(tempfile); =head1 NAME mysqlhotcopy - fast on-line hot-backup utility for local MySQL databases and tables =head1 SYNOPSIS mysqlhotcopy db_name mysqlhotcopy --suffix=_copy db_name_1 ... db_name_n mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory mysqlhotcopy db_name./regex/ mysqlhotcopy db_name./^\(foo\|bar\)/ mysqlhotcopy db_name./~regex/ mysqlhotcopy db_name_1./regex_1/ db_name_1./regex_2/ ... db_name_n./regex_n/ /path/to/new_directory mysqlhotcopy --method='scp -Bq -i /usr/home/foo/.ssh/identity' --user=root --password=secretpassword \ db_1./^nice_table/ user@some.system.dom:~/path/to/new_directory WARNING: THIS PROGRAM IS STILL IN BETA. Comments/patches welcome. =cut # Documentation continued at end of file # fix CORE::GLOBAL::die to return a predictable exit code BEGIN { *CORE::GLOBAL::die= sub { warn @_; exit 1; }; } my $VERSION = "1.23"; my $opt_tmpdir = $ENV{TMPDIR} || "/tmp"; my $OPTIONS = <<"_OPTIONS"; $0 Ver $VERSION Usage: $0 db_name[./table_regex/] [new_db_name | directory] -?, --help display this help-screen and exit -u, --user=# user for database login if not current user -p, --password=# password to use when connecting to server (if not set in my.cnf, which is recommended) -h, --host=# hostname for local server when connecting over TCP/IP -P, --port=# port to use when connecting to local server with TCP/IP -S, --socket=# socket to use when connecting to local server --old_server connect to old MySQL-server (before v5.5) which doesn't have FLUSH TABLES WITH READ LOCK fully implemented. --allowold don\'t abort if target dir already exists (rename it _old) --addtodest don\'t rename target dir if it exists, just add files to it --keepold don\'t delete previous (now renamed) target when done --noindices don\'t include full index files in copy --method=# method for copy (only "cp" currently supported) -q, --quiet be silent except for errors --debug enable debug -n, --dryrun report actions without doing them --regexp=# copy all databases with names matching regexp --suffix=# suffix for names of copied databases --checkpoint=# insert checkpoint entry into specified db.table --flushlog flush logs once all tables are locked --resetmaster reset the binlog once all tables are locked --resetslave reset the master.info once all tables are locked --tmpdir=# temporary directory (instead of $opt_tmpdir) --record_log_pos=# record slave and master status in specified db.table --chroot=# base directory of chroot jail in which mysqld operates Try \'perldoc $0\' for more complete documentation _OPTIONS sub usage { die @_, $OPTIONS; } # Do not initialize user or password options; that way, any user/password # options specified in option files will be used. If no values are specified # at all, the defaults will be used (login name, no password). my %opt = ( noindices => 0, allowold => 0, # for safety keepold => 0, method => "cp", flushlog => 0, ); Getopt::Long::Configure(qw(no_ignore_case)); # disambiguate -p and -P GetOptions( \%opt, "help", "host|h=s", "user|u=s", "password|p=s", "port|P=s", "socket|S=s", "old_server", "allowold!", "keepold!", "addtodest!", "noindices!", "method=s", "debug", "quiet|q", "mv!", "regexp=s", "suffix=s", "checkpoint=s", "record_log_pos=s", "flushlog", "resetmaster", "resetslave", "tmpdir|t=s", "dryrun|n", "chroot=s", ) or usage("Invalid option"); # @db_desc # ========== # a list of hash-refs containing: # # 'src' - name of the db to copy # 't_regex' - regex describing tables in src # 'target' - destination directory of the copy # 'tables' - array-ref to list of tables in the db # 'files' - array-ref to list of files to be copied # 'index' - array-ref to list of indexes to be copied # my @db_desc = (); my $tgt_name = undef; usage("") if ($opt{help}); if ( $opt{regexp} || $opt{suffix} || @ARGV > 2 ) { $tgt_name = pop @ARGV unless ( exists $opt{suffix} ); @db_desc = map { s{^([^\.]+)\./(.+)/$}{$1}; { 'src' => $_, 't_regex' => ( $2 ? $2 : '.*' ) } } @ARGV; } else { usage("Database name to hotcopy not specified") unless ( @ARGV ); $ARGV[0] =~ s{^([^\.]+)\./(.+)/$}{$1}; @db_desc = ( { 'src' => $ARGV[0], 't_regex' => ( $2 ? $2 : '.*' ) } ); if ( @ARGV == 2 ) { $tgt_name = $ARGV[1]; } else { $opt{suffix} = "_copy"; } } my %mysqld_vars; my $start_time = time; $opt_tmpdir= $opt{tmpdir} if $opt{tmpdir}; $0 = $1 if $0 =~ m:/([^/]+)$:; $opt{quiet} = 0 if $opt{debug}; $opt{allowold} = 1 if $opt{keepold}; # --- connect to the database --- ## Socket takes precedence. my $dsn; my $prefix= 'mysql'; if (eval {DBI->install_driver("MariaDB")}) { $dsn ="DBI:MariaDB:;"; $prefix= 'mariadb'; } else { $dsn = "DBI:mysql:;"; } if ($opt{socket} and -S $opt{socket}) { $dsn .= "${prefix}_socket=$opt{socket}"; } else { $dsn .= "host=" . $opt{host}; if ($opt{host} ne "localhost" and $opt{port}) { $dsn .= ";port=". $opt{port}; } } $dsn .= ";mariadb_read_default_group=mysqlhotcopy"; # use mariadb_read_default_group=mysqlhotcopy so that [client] and # [mysqlhotcopy] groups will be read from standard options files. # make the connection to MariaDB my $dbh= DBI->connect($dsn, $opt{user}, $opt{password}, { RaiseError => 1, PrintError => 0}) || die("Can't make a connection to the MariaDB server.\n The error: $DBI::errstr"); # --- check that checkpoint table exists if specified --- if ( $opt{checkpoint} ) { $opt{checkpoint} = quote_names( $opt{checkpoint} ); eval { $dbh->do( qq{ select time_stamp, src, dest, msg from $opt{checkpoint} where 1 != 1} ); }; die "Error accessing Checkpoint table ($opt{checkpoint}): $@" if ( $@ ); } # --- check that log_pos table exists if specified --- if ( $opt{record_log_pos} ) { $opt{record_log_pos} = quote_names( $opt{record_log_pos} ); eval { $dbh->do( qq{ select host, time_stamp, log_file, log_pos, master_host, master_log_file, master_log_pos from $opt{record_log_pos} where 1 != 1} ); }; die "Error accessing log_pos table ($opt{record_log_pos}): $@" if ( $@ ); } # --- get variables from database --- my $sth_vars = $dbh->prepare("show variables like 'datadir'"); $sth_vars->execute; while ( my ($var,$value) = $sth_vars->fetchrow_array ) { $mysqld_vars{ $var } = $value; } my $datadir = $mysqld_vars{'datadir'} || die "datadir not in mysqld variables"; $datadir= $opt{chroot}.$datadir if ($opt{chroot}); $datadir =~ s:/$::; # --- get target path --- my ($tgt_dirname, $to_other_database); $to_other_database=0; if (defined($tgt_name) && $tgt_name =~ m:^\w+$: && @db_desc <= 1) { $tgt_dirname = "$datadir/$tgt_name"; $to_other_database=1; } elsif (defined($tgt_name) && ($tgt_name =~ m:/: || $tgt_name eq '.')) { $tgt_dirname = $tgt_name; } elsif ( $opt{suffix} ) { print "Using copy suffix '$opt{suffix}'\n" unless $opt{quiet}; } else { $tgt_name="" if (!defined($tgt_name)); die "Target '$tgt_name' doesn't look like a database name or directory path.\n"; } # --- resolve database names from regexp --- if ( defined $opt{regexp} ) { my $t_regex = '.*'; if ( $opt{regexp} =~ s{^/(.+)/\./(.+)/$}{$1} ) { $t_regex = $2; } my $sth_dbs = $dbh->prepare("show databases"); $sth_dbs->execute; while ( my ($db_name) = $sth_dbs->fetchrow_array ) { next if $db_name =~ m/^information_schema$/i; next if $db_name =~ m/^performance_schema$/i; next if $db_name =~ m/^sys$/i; push @db_desc, { 'src' => $db_name, 't_regex' => $t_regex } if ( $db_name =~ m/$opt{regexp}/o ); } } # --- get list of tables and views to hotcopy --- my $hc_locks = ""; my $hc_tables = ""; my $hc_base_tables = ""; my $hc_views = ""; my $num_base_tables = 0; my $num_views = 0; my $num_tables = 0; my $num_files = 0; foreach my $rdb ( @db_desc ) { my $db = $rdb->{src}; my @dbh_base_tables = get_list_of_tables( $db ); my @dbh_views = get_list_of_views( $db ); ## filter out certain system non-lockable tables. ## keep in sync with mysqldump. if ($db =~ m/^mysql$/i) { @dbh_base_tables = grep { !/^(apply_status|schema|general_log|slow_log|transaction_registry)$/ } @dbh_base_tables } ## generate regex for tables/files my $t_regex; my $negated; if ($rdb->{t_regex}) { $t_regex = $rdb->{t_regex}; ## assign temporary regex $negated = $t_regex =~ s/^~//; ## note and remove negation operator $t_regex = qr/$t_regex/; ## make regex string from ## user regex ## filter (out) tables specified in t_regex print "Filtering tables with '$t_regex'\n" if $opt{debug}; @dbh_base_tables = ( $negated ? grep { $_ !~ $t_regex } @dbh_base_tables : grep { $_ =~ $t_regex } @dbh_base_tables ); ## filter (out) views specified in t_regex print "Filtering tables with '$t_regex'\n" if $opt{debug}; @dbh_views = ( $negated ? grep { $_ !~ $t_regex } @dbh_views : grep { $_ =~ $t_regex } @dbh_views ); } ## Now concatenate the base table and view arrays. my @dbh_tables = (@dbh_base_tables, @dbh_views); ## get list of files to copy my $db_dir = "$datadir/$db"; opendir(DBDIR, $db_dir ) or die "Cannot open dir '$db_dir': $!"; my %db_files; while ( defined( my $name = readdir DBDIR ) ) { $db_files{$name} = $1 if ( $name =~ /(.+)\.\w+$/ ); } closedir( DBDIR ); unless( keys %db_files ) { warn "'$db' is an empty database\n"; } ## filter (out) files specified in t_regex my @db_files; if ($rdb->{t_regex}) { @db_files = ($negated ? grep { $db_files{$_} !~ $t_regex } keys %db_files : grep { $db_files{$_} =~ $t_regex } keys %db_files ); } else { @db_files = keys %db_files; } @db_files = sort @db_files; my @index_files=(); ## remove indices unless we're told to keep them if ($opt{noindices}) { @index_files= grep { /\.(ISM|MYI)$/ } @db_files; @db_files = grep { not /\.(ISM|MYI)$/ } @db_files; } $rdb->{files} = [ @db_files ]; $rdb->{index} = [ @index_files ]; my @hc_base_tables = map { quote_names("$db.$_") } @dbh_base_tables; my @hc_views = map { quote_names("$db.$_") } @dbh_views; my @hc_tables = (@hc_base_tables, @hc_views); $rdb->{tables} = [ @hc_tables ]; $hc_locks .= ", " if ( length $hc_locks && @hc_tables ); $hc_locks .= join ", ", map { "$_ READ" } @hc_tables; $hc_base_tables .= ", " if ( length $hc_base_tables && @hc_base_tables ); $hc_base_tables .= join ", ", @hc_base_tables; $hc_views .= ", " if ( length $hc_views && @hc_views ); $hc_views .= join " READ, ", @hc_views; @hc_tables = (@hc_base_tables, @hc_views); $num_base_tables += scalar @hc_base_tables; $num_views += scalar @hc_views; $num_tables += $num_base_tables + $num_views; $num_files += scalar @{$rdb->{files}}; } # --- resolve targets for copies --- if (defined($tgt_name) && length $tgt_name ) { # explicit destination directory specified # GNU `cp -r` error message die "copying multiple databases, but last argument ($tgt_dirname) is not a directory\n" if ( @db_desc > 1 && !(-e $tgt_dirname && -d $tgt_dirname ) ); if ($to_other_database) { foreach my $rdb ( @db_desc ) { $rdb->{target} = "$tgt_dirname"; } } elsif ($opt{method} =~ /^scp\b/) { # we have to trust scp to hit the target foreach my $rdb ( @db_desc ) { $rdb->{target} = "$tgt_dirname/$rdb->{src}"; } } else { die "Last argument ($tgt_dirname) is not a directory\n" if (!(-e $tgt_dirname && -d $tgt_dirname ) ); foreach my $rdb ( @db_desc ) { $rdb->{target} = "$tgt_dirname/$rdb->{src}"; } } } else { die "Error: expected \$opt{suffix} to exist" unless ( exists $opt{suffix} ); foreach my $rdb ( @db_desc ) { $rdb->{target} = "$datadir/$rdb->{src}$opt{suffix}"; } } print Dumper( \@db_desc ) if ( $opt{debug} ); # --- bail out if all specified databases are empty --- die "No tables to hot-copy" unless ( length $hc_locks ); # --- create target directories if we are using 'cp' --- my @existing = (); if ($opt{method} =~ /^cp\b/) { foreach my $rdb ( @db_desc ) { push @existing, $rdb->{target} if ( -d $rdb->{target} ); } if ( @existing && !($opt{allowold} || $opt{addtodest}) ) { $dbh->disconnect(); die "Can't hotcopy to '", join( "','", @existing ), "' because directory\nalready exist and the --allowold or --addtodest options were not given.\n" } } retire_directory( @existing ) if @existing && !$opt{addtodest}; foreach my $rdb ( @db_desc ) { my $tgt_dirpath = "$rdb->{target}"; # Remove trailing slashes (needed for Mac OS X) substr($tgt_dirpath, 1) =~ s|/+$||; if ( $opt{dryrun} ) { print "mkdir $tgt_dirpath, 0750\n"; } elsif ($opt{method} =~ /^scp\b/) { ## assume it's there? ## ... } else { mkdir($tgt_dirpath, 0750) or die "Can't create '$tgt_dirpath': $!\n" unless -d $tgt_dirpath; my @f_info= stat "$datadir/$rdb->{src}"; chown $f_info[4], $f_info[5], $tgt_dirpath; } } ############################## # --- PERFORM THE HOT-COPY --- # # Note that we try to keep the time between the LOCK and the UNLOCK # as short as possible, and only start when we know that we should # be able to complete without error. # read lock all the tables we'll be copying # in order to get a consistent snapshot of the database if ( $opt{checkpoint} || $opt{record_log_pos} ) { # convert existing READ lock on checkpoint and/or log_pos table into WRITE lock foreach my $table ( grep { defined } ( $opt{checkpoint}, $opt{record_log_pos} ) ) { $hc_locks .= ", $table WRITE" unless ( $hc_locks =~ s/$table\s+READ/$table WRITE/ ); } } my $hc_started = time; # count from time lock is granted if ( $opt{dryrun} ) { if ( $opt{old_server} ) { print "LOCK TABLES $hc_locks\n"; print "FLUSH TABLES /*!32323 $hc_tables */\n"; } else { # Lock base tables and views separately. print "FLUSH TABLES $hc_base_tables WITH READ LOCK\n" if ( $hc_base_tables ); print "LOCK TABLES $hc_views READ\n" if ( $hc_views ); } print "FLUSH LOGS\n" if ( $opt{flushlog} ); print "RESET MASTER\n" if ( $opt{resetmaster} ); print "RESET SLAVE\n" if ( $opt{resetslave} ); } else { my $start = time; if ( $opt{old_server} ) { $dbh->do("LOCK TABLES $hc_locks"); printf "Locked $num_tables tables in %d seconds.\n", time-$start unless $opt{quiet}; $hc_started = time; # count from time lock is granted # flush tables to make on-disk copy up to date $start = time; $dbh->do("FLUSH TABLES /*!32323 $hc_tables */"); printf "Flushed tables ($hc_tables) in %d seconds.\n", time-$start unless $opt{quiet}; } else { # Lock base tables and views separately, as 'FLUSH TABLES <tbl_name> # ... WITH READ LOCK' (introduced in 5.5) would fail for views. # Also, flush tables to make on-disk copy up to date $dbh->do("FLUSH TABLES $hc_base_tables WITH READ LOCK") if ( $hc_base_tables ); printf "Flushed $num_base_tables tables with read lock ($hc_base_tables) in %d seconds.\n", time-$start unless $opt{quiet}; $start = time; $dbh->do("LOCK TABLES $hc_views READ") if ( $hc_views ); printf "Locked $num_views views ($hc_views) in %d seconds.\n", time-$start unless $opt{quiet}; $hc_started = time; # count from time lock is granted } $dbh->do( "FLUSH LOGS" ) if ( $opt{flushlog} ); $dbh->do( "RESET MASTER" ) if ( $opt{resetmaster} ); $dbh->do( "RESET SLAVE" ) if ( $opt{resetslave} ); if ( $opt{record_log_pos} ) { record_log_pos( $dbh, $opt{record_log_pos} ); $dbh->do("FLUSH TABLES /*!32323 $hc_tables */"); } } my @failed = (); foreach my $rdb ( @db_desc ) { my @files = map { "$datadir/$rdb->{src}/$_" } @{$rdb->{files}}; next unless @files; eval { copy_files($opt{method}, \@files, $rdb->{target}); }; push @failed, "$rdb->{src} -> $rdb->{target} failed: $@" if ( $@ ); @files = @{$rdb->{index}}; if ($rdb->{index}) { copy_index($opt{method}, \@files, "$datadir/$rdb->{src}", $rdb->{target} ); } if ( $opt{checkpoint} ) { my $msg = ( $@ ) ? "Failed: $@" : "Succeeded"; eval { $dbh->do( qq{ insert into $opt{checkpoint} (src, dest, msg) VALUES ( '$rdb->{src}', '$rdb->{target}', '$msg' ) } ); }; if ( $@ ) { warn "Failed to update checkpoint table: $@\n"; } } } if ( $opt{dryrun} ) { print "UNLOCK TABLES\n"; if ( @existing && !$opt{keepold} ) { my @oldies = map { $_ . '_old' } @existing; print "rm -rf @oldies\n" } $dbh->disconnect(); exit(0); } else { $dbh->do("UNLOCK TABLES"); } my $hc_dur = time - $hc_started; printf "Unlocked tables.\n" unless $opt{quiet}; # # --- HOT-COPY COMPLETE --- ########################### $dbh->disconnect; if ( @failed ) { # hotcopy failed - cleanup # delete any @targets # rename _old copy back to original my @targets = (); foreach my $rdb ( @db_desc ) { push @targets, $rdb->{target} if ( -d $rdb->{target} ); } print "Deleting @targets \n" if $opt{debug}; print "Deleting @targets \n" if $opt{debug}; rmtree([@targets]); if (@existing) { print "Restoring @existing from back-up\n" if $opt{debug}; foreach my $dir ( @existing ) { rename("${dir}_old", $dir ) or warn "Can't rename ${dir}_old to $dir: $!\n"; } } die join( "\n", @failed ); } else { # hotcopy worked # delete _old unless $opt{keepold} if ( @existing && !$opt{keepold} ) { my @oldies = map { $_ . '_old' } @existing; print "Deleting previous copy in @oldies\n" if $opt{debug}; rmtree([@oldies]); } printf "$0 copied %d tables (%d files) in %d second%s (%d seconds overall).\n", $num_tables, $num_files, $hc_dur, ($hc_dur==1)?"":"s", time - $start_time unless $opt{quiet}; } exit 0; # --- sub copy_files { my ($method, $files, $target) = @_; my @cmd; print "Copying ".@$files." files...\n" unless $opt{quiet}; if ($method =~ /^s?cp\b/) # cp or scp with optional flags { my $cp = $method; # add option to preserve mod time etc of copied files # not critical, but nice to have $cp.= " -p" if $^O =~ m/^(solaris|linux|freebsd|darwin)$/; # add recursive option for scp $cp.= " -r" if $^O =~ /m^(solaris|linux|freebsd|darwin)$/ && $method =~ /^scp\b/; # perform the actual copy safe_system( $cp, (map { "'$_'" } @$files), "'$target'" ); } else { die "Can't use unsupported method '$method'\n"; } } # # Copy only the header of the index file # sub copy_index { my ($method, $files, $source, $target) = @_; print "Copying indices for ".@$files." files...\n" unless $opt{quiet}; foreach my $file (@$files) { my $from="$source/$file"; my $to="$target/$file"; my $buff; open(INPUT, "<$from") || die "Can't open file $from: $!\n"; binmode(INPUT, ":raw"); my $length=read INPUT, $buff, 2048; die "Can't read index header from $from\n" if ($length < 1024); close INPUT; if ( $opt{dryrun} ) { print "$opt{method}-header $from $to\n"; } elsif ($opt{method} eq 'cp') { open(OUTPUT,">$to") || die "Can\'t create file $to: $!\n"; if (syswrite(OUTPUT,$buff) != length($buff)) { die "Error when writing data to $to: $!\n"; } close OUTPUT || die "Error on close of $to: $!\n"; } elsif ($opt{method} =~ /^scp\b/) { my ($fh, $tmp)= tempfile('mysqlhotcopy-XXXXXX', DIR => $opt_tmpdir) or die "Can\'t create/open file in $opt_tmpdir\n"; if (syswrite($fh,$buff) != length($buff)) { die "Error when writing data to $tmp: $!\n"; } close $fh || die "Error on close of $tmp: $!\n"; safe_system("$opt{method} $tmp $to"); unlink $tmp; } else { die "Can't use unsupported method '$opt{method}'\n"; } } } sub safe_system { my @sources= @_; my $method= shift @sources; my $target= pop @sources; ## @sources = list of source file names ## We have to deal with very long command lines, otherwise they may generate ## "Argument list too long". ## With 10000 tables the command line can be around 1MB, much more than 128kB ## which is the common limit on Linux (can be read from ## /usr/src/linux/include/linux/binfmts.h ## see http://www.linuxjournal.com/article.php?sid=6060). my $chunk_limit= 100 * 1024; # 100 kB my @chunk= (); my $chunk_length= 0; foreach (@sources) { push @chunk, $_; $chunk_length+= length($_); if ($chunk_length > $chunk_limit) { safe_simple_system($method, @chunk, $target); @chunk=(); $chunk_length= 0; } } if ($chunk_length > 0) { # do not forget last small chunk safe_simple_system($method, @chunk, $target); } } sub safe_simple_system { my @cmd= @_; if ( $opt{dryrun} ) { print "@cmd\n"; } else { ## for some reason system fails but backticks works ok for scp... print "Executing '@cmd'\n" if $opt{debug}; my $cp_status = system "@cmd > /dev/null"; if ($cp_status != 0) { warn "Executing command failed ($cp_status). Trying backtick execution...\n"; ## try something else `@cmd` || die "Error: @cmd failed ($?) while copying files.\n"; } } } sub retire_directory { my ( @dir ) = @_; foreach my $dir ( @dir ) { my $tgt_oldpath = $dir . '_old'; if ( $opt{dryrun} ) { print "rmtree $tgt_oldpath\n" if ( -d $tgt_oldpath ); print "rename $dir, $tgt_oldpath\n"; next; } if ( -d $tgt_oldpath ) { print "Deleting previous 'old' hotcopy directory ('$tgt_oldpath')\n" unless $opt{quiet}; rmtree([$tgt_oldpath],0,1); } rename($dir, $tgt_oldpath) or die "Can't rename $dir=>$tgt_oldpath: $!\n"; print "Existing hotcopy directory renamed to '$tgt_oldpath'\n" unless $opt{quiet}; } } sub record_log_pos { my ( $dbh, $table_name ) = @_; eval { my ($file,$position) = get_row( $dbh, "show master status" ); die "master status is undefined" if !defined $file || !defined $position; my $row_hash = get_row_hash( $dbh, "show slave status" ); my ($master_host, $log_file, $log_pos ); if ( $dbh->{mariadb_serverinfo} =~ /^3\.23/ ) { ($master_host, $log_file, $log_pos ) = @{$row_hash}{ qw / Master_Host Log_File Pos / }; } else { ($master_host, $log_file, $log_pos ) = @{$row_hash}{ qw / Master_Host Relay_Master_Log_File Exec_Master_Log_Pos / }; } my $hostname = hostname(); $dbh->do( qq{ replace into $table_name set host=?, log_file=?, log_pos=?, master_host=?, master_log_file=?, master_log_pos=? }, undef, $hostname, $file, $position, $master_host, $log_file, $log_pos ); }; if ( $@ ) { warn "Failed to store master position: $@\n"; } } sub get_row { my ( $dbh, $sql ) = @_; my $sth = $dbh->prepare($sql); $sth->execute; return $sth->fetchrow_array(); } sub get_row_hash { my ( $dbh, $sql ) = @_; my $sth = $dbh->prepare($sql); $sth->execute; return $sth->fetchrow_hashref(); } sub get_list_of_tables { my ( $db ) = @_; my $tables = eval { $dbh->selectall_arrayref('SHOW FULL TABLES FROM ' . $dbh->quote_identifier($db) . ' WHERE Table_type = \'BASE TABLE\'') } || []; warn "Unable to retrieve list of tables in $db: $@" if $@; return (map { $_->[0] } @$tables); } sub get_list_of_views { my ( $db ) = @_; my $views = eval { $dbh->selectall_arrayref('SHOW FULL TABLES FROM ' . $dbh->quote_identifier($db) . ' WHERE Table_type = \'VIEW\'') } || []; warn "Unable to retrieve list of views in $db: $@" if $@; return (map { $_->[0] } @$views); } sub quote_names { my ( $name ) = @_; # given a db.table name, add quotes my ($db, $table, @cruft) = split( /\./, $name ); die "Invalid db.table name '$name'" if (@cruft || !defined $db || !defined $table ); # Earlier versions of DBD return table name non-quoted, # such as DBD-2.1012 and the newer ones, such as DBD-2.9002 # returns it quoted. Let's have a support for both. $table=~ s/\`//g; return "`$db`.`$table`"; } __END__ =head1 DESCRIPTION mysqlhotcopy is designed to make stable copies of live MySQL databases. Here "live" means that the database server is running and the database may be in active use. And "stable" means that the copy will not have any corruptions that could occur if the table files were simply copied without first being locked and flushed from within the server. =head1 OPTIONS =over 4 =item --checkpoint checkpoint-table As each database is copied, an entry is written to the specified checkpoint-table. This has the happy side-effect of updating the MySQL update-log (if it is switched on) giving a good indication of where roll-forward should begin for backup+rollforward schemes. The name of the checkpoint table should be supplied in database.table format. The checkpoint-table must contain at least the following fields: =over 4 time_stamp timestamp not null src varchar(32) dest varchar(60) msg varchar(255) =back =item --record_log_pos log-pos-table Just before the database files are copied, update the record in the log-pos-table from the values returned from "show master status" and "show slave status". The master status values are stored in the log_file and log_pos columns, and establish the position in the binary logs that any slaves of this host should adopt if initialised from this dump. The slave status values are stored in master_host, master_log_file, and master_log_pos, corresponding to the coordinates of the next to the last event the slave has executed. The slave or its siblings can connect to the master next time and request replication starting from the recorded values. The name of the log-pos table should be supplied in database.table format. A sample log-pos table definition: =over 4 CREATE TABLE log_pos ( host varchar(60) NOT null, time_stamp timestamp NOT NULL, log_file varchar(32) default NULL, log_pos int(11) default NULL, master_host varchar(60) NULL, master_log_file varchar(32) NULL, master_log_pos int NULL, PRIMARY KEY (host) ); =back =item --suffix suffix Each database is copied back into the originating datadir under a new name. The new name is the original name with the suffix appended. If only a single db_name is supplied and the --suffix flag is not supplied, then "--suffix=_copy" is assumed. =item --allowold Move any existing version of the destination to a backup directory for the duration of the copy. If the copy successfully completes, the backup directory is deleted - unless the --keepold flag is set. If the copy fails, the backup directory is restored. The backup directory name is the original name with "_old" appended. Any existing versions of the backup directory are deleted. =item --keepold Behaves as for the --allowold, with the additional feature of keeping the backup directory after the copy successfully completes. =item --addtodest Don't rename target directory if it already exists, just add the copied files into it. This is most useful when backing up a database with many large tables and you don't want to have all the tables locked for the whole duration. In this situation, I<if> you are happy for groups of tables to be backed up separately (and thus possibly not be logically consistent with one another) then you can run mysqlhotcopy several times on the same database each with different db_name./table_regex/. All but the first should use the --addtodest option so the tables all end up in the same directory. =item --flushlog Rotate the log files by executing "FLUSH LOGS" after all tables are locked, and before they are copied. =item --resetmaster Reset the bin-log by executing "RESET MASTER" after all tables are locked, and before they are copied. Useful if you are recovering a slave in a replication setup. =item --resetslave Reset the master.info by executing "RESET SLAVE" after all tables are locked, and before they are copied. Useful if you are recovering a server in a mutual replication setup. =item --regexp pattern Copy all databases with names matching the pattern. =item --regexp /pattern1/./pattern2/ Copy all tables with names matching pattern2 from all databases with names matching pattern1. For example, to select all tables which names begin with 'bar' from all databases which names end with 'foo': mysqlhotcopy --indices --method=cp --regexp /foo$/./^bar/ =item db_name./pattern/ Copy only tables matching pattern. Shell metacharacters ( (, ), |, !, etc.) have to be escaped (e.g., \). For example, to select all tables in database db1 whose names begin with 'foo' or 'bar': mysqlhotcopy --indices --method=cp db1./^\(foo\|bar\)/ =item db_name./~pattern/ Copy only tables not matching pattern. For example, to copy tables that do not begin with foo nor bar: mysqlhotcopy --indices --method=cp db1./~^\(foo\|bar\)/ =item -?, --help Display help-screen and exit. =item -u, --user=# User for database login if not current user. =item -p, --password=# Password to use when connecting to the server. Note that you are strongly encouraged *not* to use this option as every user would be able to see the password in the process list. Instead use the '[mysqlhotcopy]' section in one of the config files, normally /etc/my.cnf or your personal ~/.my.cnf. (See the chapter 'my.cnf Option Files' in the manual.) =item -h, -h, --host=# Hostname for local server when connecting over TCP/IP. By specifying this different from 'localhost' will trigger mysqlhotcopy to use TCP/IP connection. =item -P, --port=# Port to use when connecting to MySQL server with TCP/IP. This is only used when using the --host option. =item -S, --socket=# UNIX domain socket to use when connecting to local server. =item --old_server Use old server (pre v5.5) commands. =item --noindices Don\'t include index files in copy. Only up to the first 2048 bytes are copied; You can restore the indexes with isamchk -r or myisamchk -r on the backup. =item --method=# Method for copy (only "cp" currently supported). Alpha support for "scp" was added in November 2000. Your experience with the scp method will vary with your ability to understand how scp works. 'man scp' and 'man ssh' are your friends. The destination directory _must exist_ on the target machine using the scp method. --keepold and --allowold are meaningless with scp. Liberal use of the --debug option will help you figure out what\'s really going on when you do an scp. Note that using scp will lock your tables for a _long_ time unless your network connection is _fast_. If this is unacceptable to you, use the 'cp' method to copy the tables to some temporary area and then scp or rsync the files at your leisure. =item -q, --quiet Be silent except for errors. =item --debug Debug messages are displayed. =item -n, --dryrun Display commands without actually doing them. =back =head1 WARRANTY This software is free and comes without warranty of any kind. You should never trust backup software without studying the code yourself. Study the code inside this script and only rely on it if I<you> believe that it does the right thing for you. Patches adding bug fixes, documentation and new features are welcome. Please send these to internals@lists.mysql.com. =head1 TO DO Extend the individual table copy to allow multiple subsets of tables to be specified on the command line: mysqlhotcopy db newdb t1 t2 /^foo_/ : t3 /^bar_/ : + where ":" delimits the subsets, the /^foo_/ indicates all tables with names beginning with "foo_" and the "+" indicates all tables not copied by the previous subsets. 'newdb' is either the name of the new database, or the full path name of the new database file. The database should not already exist. Add option to lock each table in turn for people who don\'t need cross-table integrity. Add option to FLUSH STATUS just before UNLOCK TABLES. Add support for other copy methods (e.g., tar to single file?). Add support for forthcoming MySQL ``RAID'' table subdirectory layouts. =head1 AUTHOR Tim Bunce Martin Waite - Added checkpoint, flushlog, regexp and dryrun options. Fixed cleanup of targets when hotcopy fails. Added --record_log_pos. RAID tables are now copied (don't know if this works over scp). Ralph Corderoy - Added synonyms for commands. Scott Wiersdorf - Added table regex and scp support. Monty - Working --noindex (copy only first 2048 bytes of index file). Fixes for --method=scp. Ask Bjoern Hansen - Cleanup code to fix a few bugs and enable -w again. Emil S. Hansen - Added resetslave and resetmaster. Jeremy D. Zawodny - Removed deprecated DBI calls. Fixed bug which resulted in nothing being copied when a regexp was specified but no database name(s). Martin Waite - Fix to handle database name that contains space. Paul DuBois - Remove end '/' from directory names.
Save
cmd:
run