diff --git a/.gitignore b/.gitignore
index 3f1a5d6b..90bd720f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,5 @@ jtester.properties
.idea/
*.iml
.DS_Store
+*.tar.gz
+*.rpm
diff --git a/deployer/src/main/java/com/alibaba/otter/canal/deployer/CanalController.java b/deployer/src/main/java/com/alibaba/otter/canal/deployer/CanalController.java
index 88f6e9a3..0a2c91f8 100644
--- a/deployer/src/main/java/com/alibaba/otter/canal/deployer/CanalController.java
+++ b/deployer/src/main/java/com/alibaba/otter/canal/deployer/CanalController.java
@@ -379,7 +379,18 @@ public class CanalController {
}
private String getProperty(Properties properties, String key) {
- return StringUtils.trim(properties.getProperty(StringUtils.trim(key)));
+ key = StringUtils.trim(key);
+ String value = System.getProperty(key);
+
+ if (value == null) {
+ value = System.getenv(key);
+ }
+
+ if (value == null) {
+ value = properties.getProperty(key);
+ }
+
+ return StringUtils.trim(value);
}
public void start() throws Throwable {
diff --git a/deployer/src/main/resources/canal.properties b/deployer/src/main/resources/canal.properties
index 0a11a5c9..2bff29ae 100644
--- a/deployer/src/main/resources/canal.properties
+++ b/deployer/src/main/resources/canal.properties
@@ -3,7 +3,7 @@
#################################################
canal.id= 1
canal.ip=
-canal.port= 11111
+canal.port=11111
canal.zkServers=
# flush data to zk
canal.zookeeper.flush.period = 1000
@@ -59,6 +59,13 @@ canal.instance.parser.parallel = true
## disruptor ringbuffer size, must be power of 2
canal.instance.parser.parallelBufferSize = 256
+# table meta tsdb info
+canal.instance.tsdb.enable=true
+canal.instance.tsdb.dir=${canal.file.data.dir:../conf}/${canal.instance.destination:}
+canal.instance.tsdb.url=jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
+canal.instance.tsdb.dbUsername=canal
+canal.instance.tsdb.dbPassword=canal
+
#################################################
######### destinations #############
#################################################
diff --git a/deployer/src/main/resources/example/instance.properties b/deployer/src/main/resources/example/instance.properties
index a3703b86..e0cf0064 100644
--- a/deployer/src/main/resources/example/instance.properties
+++ b/deployer/src/main/resources/example/instance.properties
@@ -1,11 +1,12 @@
#################################################
-## mysql serverId
-canal.instance.mysql.slaveId=0
+## mysql serverId , v1.0.26+ will autoGen
+# canal.instance.mysql.slaveId=0
+
+# enable gtid use true/false
+canal.instance.gtidon=false
# position info
canal.instance.master.address=127.0.0.1:3306
-# enable gtid use true/false
-canal.instance.gtidon=false
canal.instance.master.journal.name=
canal.instance.master.position=
canal.instance.master.timestamp=
@@ -13,23 +14,21 @@ canal.instance.master.gtid=
# table meta tsdb info
canal.instance.tsdb.enable=true
-canal.instance.tsdb.dir=${canal.file.data.dir:../conf}/${canal.instance.destination:}
-canal.instance.tsdb.url=jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
#canal.instance.tsdb.url=jdbc:mysql://127.0.0.1:3306/canal_tsdb
-canal.instance.tsdb.dbUsername=canal
-canal.instance.tsdb.dbPassword=canal
-
+#canal.instance.tsdb.dbUsername=canal
+#canal.instance.tsdb.dbPassword=canal
#canal.instance.standby.address =
#canal.instance.standby.journal.name =
#canal.instance.standby.position =
#canal.instance.standby.timestamp =
#canal.instance.standby.gtid=
+
# username/password
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
-canal.instance.defaultDatabaseName=test
canal.instance.connectionCharset=UTF-8
+
# table regex
canal.instance.filter.regex=.*\\..*
# table black regex
diff --git a/deployer/src/main/resources/spring/default-instance.xml b/deployer/src/main/resources/spring/default-instance.xml
index 9bf28896..6b455c83 100644
--- a/deployer/src/main/resources/spring/default-instance.xml
+++ b/deployer/src/main/resources/spring/default-instance.xml
@@ -149,7 +149,7 @@
-
+
@@ -157,7 +157,7 @@
-
+
diff --git a/deployer/src/main/resources/spring/file-instance.xml b/deployer/src/main/resources/spring/file-instance.xml
index 6d263717..377428a9 100644
--- a/deployer/src/main/resources/spring/file-instance.xml
+++ b/deployer/src/main/resources/spring/file-instance.xml
@@ -134,7 +134,7 @@
-
+
@@ -142,7 +142,7 @@
-
+
diff --git a/deployer/src/main/resources/spring/group-instance.xml b/deployer/src/main/resources/spring/group-instance.xml
index 60ceff01..44f1ab3b 100644
--- a/deployer/src/main/resources/spring/group-instance.xml
+++ b/deployer/src/main/resources/spring/group-instance.xml
@@ -131,7 +131,7 @@
-
+
@@ -139,7 +139,7 @@
-
+
@@ -229,7 +229,7 @@
-
+
@@ -237,7 +237,7 @@
-
+
diff --git a/deployer/src/main/resources/spring/local-instance.xml b/deployer/src/main/resources/spring/local-instance.xml
index 2020d0d6..930ecb7b 100644
--- a/deployer/src/main/resources/spring/local-instance.xml
+++ b/deployer/src/main/resources/spring/local-instance.xml
@@ -114,7 +114,7 @@
-
+
diff --git a/deployer/src/main/resources/spring/memory-instance.xml b/deployer/src/main/resources/spring/memory-instance.xml
index c08f3f12..cd387b8f 100644
--- a/deployer/src/main/resources/spring/memory-instance.xml
+++ b/deployer/src/main/resources/spring/memory-instance.xml
@@ -122,7 +122,7 @@
-
+
@@ -130,7 +130,7 @@
-
+
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 00000000..e44796cb
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,67 @@
+FROM centos:centos6.7
+
+MAINTAINER agapple (jianghang115@gmail.com)
+
+# install system
+RUN \
+ /bin/cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
+ echo 'root:Hello1234' | chpasswd && \
+ groupadd -r admin && useradd -g admin admin && \
+ yum install -y man && \
+ yum install -y dstat && \
+ yum install -y unzip && \
+ yum install -y nc && \
+ yum install -y openssh-server && \
+ yum install -y tar && \
+ yum install -y which && \
+ yum install -y wget && \
+ yum install -y perl && \
+ yum install -y file && \
+ ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_dsa_key && \
+ ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key && \
+ sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd && \
+ sed -i -e 's/^#Port 22$/Port 2222/' /etc/ssh/sshd_config && \
+ mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh && \
+ yum install -y cronie && \
+ sed -i '/session required pam_loginuid.so/d' /etc/pam.d/crond && \
+ yum clean all && \
+ true
+
+# install canal
+COPY image/ /tmp/docker/
+COPY canal.deployer-*.tar.gz /home/admin/
+COPY jdk-8-linux-x64.rpm /tmp/
+
+RUN \
+ cp -R /tmp/docker/alidata /alidata && \
+ chmod +x /alidata/bin/* && \
+ mkdir -p /home/admin && \
+ cp -R /tmp/docker/admin/* /home/admin/ && \
+ /bin/cp -f alidata/bin/lark-wait /usr/bin/lark-wait && \
+
+ touch /var/lib/rpm/* && \
+ yum -y install /tmp/jdk-8-linux-x64.rpm && \
+ /bin/rm -f /tmp/jdk-8-linux-x64.rpm && \
+
+ echo "export JAVA_HOME=/usr/java/latest" >> /etc/profile && \
+ echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> /etc/profile && \
+ /bin/mv /home/admin/bin/clean_log /etc/cron.d && \
+
+ mkdir -p /home/admin/canal-server && \
+ tar -xzvf /home/admin/canal.deployer-*.tar.gz -C /home/admin/canal-server && \
+ /bin/rm -f /home/admin/canal.deployer-*.tar.gz && \
+
+ mkdir -p home/admin/canal-server/logs && \
+ chmod +x /home/admin/*.sh && \
+ chmod +x /home/admin/bin/*.sh && \
+ chown admin: -R /home/admin && \
+ yum clean all && \
+ true
+
+# 2222 sys , 8080 web , 8000 debug , 11111 canal
+EXPOSE 2222 11111 8000 8080
+
+WORKDIR /home/admin
+
+ENTRYPOINT [ "/alidata/bin/main.sh" ]
+CMD [ "/home/admin/app.sh" ]
\ No newline at end of file
diff --git a/docker/build.sh b/docker/build.sh
new file mode 100644
index 00000000..58424fb3
--- /dev/null
+++ b/docker/build.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+current_path=`pwd`
+case "`uname`" in
+ Darwin)
+ bin_abs_path=`cd $(dirname $0); pwd`
+ ;;
+ Linux)
+ bin_abs_path=$(readlink -f $(dirname $0))
+ ;;
+ *)
+ bin_abs_path=`cd $(dirname $0); pwd`
+ ;;
+esac
+BASE=${bin_abs_path}
+
+if [ ! -f $BASE/jdk*.rpm ] ; then
+ DOWNLOAD_LINK="http://download.oracle.com/otn-pub/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6ed6d1/jdk-8u181-linux-x64.tar.gz"
+ wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=xxx; oraclelicense=accept-securebackup-cookie" "$DOWNLOAD_LINK" -O $BASE/jdk-8-linux-x64.rpm
+fi
+
+cd $BASE/../ && mvn clean package -Dmaven.test.skip -Denv=release && cd $current_path ;
+
+if [ "$1" == "kafka" ] ; then
+ cp $BASE/../target/canal-kafka-*.tar.gz $BASE/
+ docker build --no-cache -t canal/canal-server $BASE/
+else
+ cp $BASE/../target/canal.deployer-*.tar.gz $BASE/
+ docker build --no-cache -t canal/canal-server $BASE/
+fi
diff --git a/docker/image/admin/app.sh b/docker/image/admin/app.sh
new file mode 100755
index 00000000..254f7e48
--- /dev/null
+++ b/docker/image/admin/app.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+set -e
+
+source /etc/profile
+export JAVA_HOME=/usr/java/latest
+export PATH=$JAVA_HOME/bin:$PATH
+touch /tmp/start.log
+chown admin: /tmp/start.log
+chown -R admin: /home/admin/canal-server
+host=`hostname -i`
+
+# waitterm
+# wait TERM/INT signal.
+# see: http://veithen.github.io/2014/11/16/sigterm-propagation.html
+waitterm() {
+ local PID
+ # any process to block
+ tail -f /dev/null &
+ PID="$!"
+ # setup trap, could do nothing, or just kill the blocker
+ trap "kill -TERM ${PID}" TERM INT
+ # wait for signal, ignore wait exit code
+ wait "${PID}" || true
+ # clear trap
+ trap - TERM INT
+ # wait blocker, ignore blocker exit code
+ wait "${PID}" 2>/dev/null || true
+}
+
+# waittermpid "${PIDFILE}".
+# monitor process by pidfile && wait TERM/INT signal.
+# if the process disappeared, return 1, means exit with ERROR.
+# if TERM or INT signal received, return 0, means OK to exit.
+waittermpid() {
+ local PIDFILE PID do_run error
+ PIDFILE="${1?}"
+ do_run=true
+ error=0
+ trap "do_run=false" TERM INT
+ while "${do_run}" ; do
+ PID="$(cat "${PIDFILE}")"
+ if ! ps -p "${PID}" >/dev/null 2>&1 ; then
+ do_run=false
+ error=1
+ else
+ sleep 1
+ fi
+ done
+ trap - TERM INT
+ return "${error}"
+}
+
+
+function checkStart() {
+ local name=$1
+ local cmd=$2
+ local timeout=$3
+ cost=5
+ while [ $timeout -gt 0 ]; do
+ ST=`eval $cmd`
+ if [ "$ST" == "0" ]; then
+ sleep 1
+ let timeout=timeout-1
+ let cost=cost+1
+ elif [ "$ST" == "" ]; then
+ sleep 1
+ let timeout=timeout-1
+ let cost=cost+1
+ else
+ break
+ fi
+ done
+ echo "start $name successful"
+}
+
+
+function start_canal() {
+ echo "start canal ..."
+ serverPort=`perl -le 'print $ENV{"canal.port"}'`
+ if [ -z "$serverPort" ] ; then
+ serverPort=11111
+ fi
+
+ destination=`perl -le 'print $ENV{"canal.destinations"}'`
+ if [[ "$destination" =~ ',' ]]; then
+ echo "multi destination:$destination is not support"
+ exit 1;
+ else
+ mv /home/admin/canal-server/conf/example /home/admin/canal-server/conf/$destination
+ fi
+ su admin -c 'cd /home/admin/canal-server/bin/ && sh restart.sh 1>>/tmp/start.log 2>&1'
+ sleep 5
+ #check start
+ checkStart "canal" "nc 127.0.0.1 $serverPort -w 1 -z | wc -l" 30
+}
+
+function stop_canal() {
+ echo "stop canal"
+ su admin -c 'cd /home/admin/canal-server/bin/ && sh stop.sh 1>>/tmp/start.log 2>&1'
+ echo "stop canal successful ..."
+}
+
+echo "==> START ..."
+
+start_canal
+
+echo "==> START SUCCESSFUL ..."
+
+tail -f /dev/null &
+# wait TERM signal
+waitterm
+
+echo "==> STOP"
+
+stop_canal
+
+echo "==> STOP SUCCESSFUL ..."
diff --git a/docker/image/admin/bin/clean_log b/docker/image/admin/bin/clean_log
new file mode 100644
index 00000000..df183614
--- /dev/null
+++ b/docker/image/admin/bin/clean_log
@@ -0,0 +1,2 @@
+# cron clean log once per minute
+*/2 * * * * admin /home/admin/bin/clean_log.sh >>/tmp/clean_log.log 2>&1
diff --git a/docker/image/admin/bin/clean_log.sh b/docker/image/admin/bin/clean_log.sh
new file mode 100755
index 00000000..9d0a0bef
--- /dev/null
+++ b/docker/image/admin/bin/clean_log.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# Global Settings
+PATH="$HOME/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin"
+export PATH
+
+CUTOFF="85"
+#获取磁盘使用率最高的分区
+USAGE=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1)
+before=$USAGE
+
+baseClean(){
+ #删除tmp目录15天前的文件。
+ #更新文档时间戳
+ if [ -d /tmp/hsperfdata_admin ]
+ then
+ touch /tmp/hsperfdata_admin
+ touch /tmp/hsperfdata_admin/*
+ fi
+
+ find /tmp/ -type f -mtime +15 | xargs -t rm -rf >/dev/null 2>&1
+
+
+ now=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1)
+ echo "before:$before; now:$now"
+}
+
+CANAL_DIR="/home/admin/canal-server/logs"
+if [[ -d $CANAL_DIR ]]; then
+ USAGE=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1)
+ if [[ $USAGE -ge 90 ]]; then
+ find $CANAL_DIR -type f -mtime +7 | xargs rm -rf {}
+ fi
+ USAGE=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1)
+ if [[ $USAGE -ge 80 ]]; then
+ find $CANAL_DIR -type f -mtime +3 | xargs rm -rf {}
+ fi
+ USAGE=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1)
+ if [[ $USAGE -ge 80 ]]; then
+ find $CANAL_DIR -type d -empty -mtime +3 | grep -v canal | xargs rm -rf {}
+ find $CANAL_DIR -type f -iname '*.tmp' | xargs rm -rf {}
+ fi
+ baseClean
+ exit 0
+fi
\ No newline at end of file
diff --git a/docker/image/admin/health.sh b/docker/image/admin/health.sh
new file mode 100755
index 00000000..17a89740
--- /dev/null
+++ b/docker/image/admin/health.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+CHECK_URL="http://127.0.0.1:8080/metrics"
+CHECK_POINT="success"
+CHECK_COUNT=`curl -s --connect-timeout 7 --max-time 7 $CHECK_URL | grep -c $CHECK_POINT`
+if [ $CHECK_COUNT -eq 0 ]; then
+ echo "[FAILED]"
+ status=0
+ error=1
+else
+ echo "[ OK ]"
+ status=1
+ error=0
+fi
\ No newline at end of file
diff --git a/docker/image/alidata/bin/exec_rc_local.sh b/docker/image/alidata/bin/exec_rc_local.sh
new file mode 100755
index 00000000..7cc8aa3f
--- /dev/null
+++ b/docker/image/alidata/bin/exec_rc_local.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+if [ "${SKIP_EXEC_RC_LOCAL}" = "YES" ] ; then
+ echo "skip /etc/rc.local: SKIP_EXEC_RC_LOCAL=${SKIP_EXEC_RC_LOCAL}"
+ exit
+fi
+
+if [ "${DOCKER_DEPLOY_TYPE}" = "HOST" ] ; then
+ echo "skip /etc/rc.local: DOCKER_DEPLOY_TYPE=${DOCKER_DEPLOY_TYPE}"
+ exit
+fi
\ No newline at end of file
diff --git a/docker/image/alidata/bin/lark-wait b/docker/image/alidata/bin/lark-wait
new file mode 100755
index 00000000..db7be708
--- /dev/null
+++ b/docker/image/alidata/bin/lark-wait
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -e
+
+chown admin: -R /home/admin/
+source /alidata/lib/proc.sh
+waitterm
diff --git a/docker/image/alidata/bin/main.sh b/docker/image/alidata/bin/main.sh
new file mode 100755
index 00000000..a57551a7
--- /dev/null
+++ b/docker/image/alidata/bin/main.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+[ -n "${DOCKER_DEPLOY_TYPE}" ] || DOCKER_DEPLOY_TYPE="VM"
+echo "DOCKER_DEPLOY_TYPE=${DOCKER_DEPLOY_TYPE}"
+
+# run init scripts
+for e in $(ls /alidata/init/*) ; do
+ [ -x "${e}" ] || continue
+ echo "==> INIT $e"
+ $e
+ echo "==> EXIT CODE: $?"
+done
+
+echo "==> INIT DEFAULT"
+service sshd start
+service crond start
+
+#echo "check hostname -i: `hostname -i`"
+#hti_num=`hostname -i|awk '{print NF}'`
+#if [ $hti_num -gt 1 ];then
+# echo "hostname -i result error:`hostname -i`"
+# exit 120
+#fi
+
+echo "==> INIT DONE"
+echo "==> RUN ${*}"
+exec "${@}"
\ No newline at end of file
diff --git a/docker/image/alidata/init/02init-sshd.sh b/docker/image/alidata/init/02init-sshd.sh
new file mode 100755
index 00000000..118ee553
--- /dev/null
+++ b/docker/image/alidata/init/02init-sshd.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# set port
+if [ -z "${SSHD_PORT}" ] ; then
+ SSHD_PORT=22
+ [ "${DOCKER_DEPLOY_TYPE}" = "HOST" ] && SSHD_PORT=2222
+fi
+
+sed -r -i '/^OPTIONS=/ d' /etc/sysconfig/sshd
+echo 'OPTIONS="-p '"${SSHD_PORT}"'"' >> /etc/sysconfig/sshd
+
+# set admin ssh pulic key
+if [ "${USE_ADMIN_PASSAGE}" = "YES" ] ; then
+ echo "set admin passage"
+ mkdir -p /home/admin/.ssh
+ chown admin:admin /home/admin/.ssh
+ chown admin:admin /home/admin/.ssh/authorized_keys
+ chmod 644 /home/admin/.ssh/authorized_keys
+fi
diff --git a/docker/image/alidata/init/fix-hosts.py b/docker/image/alidata/init/fix-hosts.py
new file mode 100755
index 00000000..4ee8abb5
--- /dev/null
+++ b/docker/image/alidata/init/fix-hosts.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#****************************************************************#
+# Create Date: 2017-01-06 17:58
+#***************************************************************#
+
+import socket
+import shutil
+from time import gmtime, strftime
+
+# get host_name
+host_name = socket.gethostname()
+tmp_file = "/tmp/.lark-fix-host.hosts"
+host_file = "/etc/hosts"
+bak_file_name = "/tmp/hosts-fix-bak.%s" % ( strftime("%Y-%m-%d_%H-%M-%S", gmtime()) )
+
+# load /etc/hosts file context
+FH = open(host_file,"r")
+file_lines = [ i.rstrip() for i in FH.readlines()]
+FH.close()
+file_lines_reverse = file_lines[::-1]
+new_lines = []
+bad_lines = []
+last_match_line = ""
+
+for line in file_lines_reverse:
+ if line.find(host_name) < 0: # 不匹配的行直接跳过
+ new_lines.append(line + "\n")
+ continue
+
+ cols = line.split()
+ new_cols = []
+ if cols[0].startswith("#"): # 跳过已经注释掉的行
+ new_lines.append(line + "\n")
+ continue
+ for col in cols:
+ if not col == host_name: # 跳过不匹配的列
+ new_cols.append(col)
+ continue
+
+ if cols[0] == "127.0.0.1": # 如果第一列是 127.0.0.1 就跳过匹配的列, 防止 hostname -i 返回 127.0.0.1
+ continue
+
+ # 如果已经发现过匹配的列, 就丢掉重复的列
+ if not len(last_match_line) == 0:
+ continue
+
+ new_cols.append(col)
+ last_match_line = line
+
+ # 跳过 xx.xx.xx.xx hostname 这样的重复列
+ if len(new_cols) == 1:
+ continue
+
+ new_l = "%s\n" % " ".join(new_cols)
+ new_lines.append(new_l)
+
+# save tmp hosts
+
+FH2=file(tmp_file,"w+")
+FH2.writelines( new_lines[::-1])
+FH2.close()
+
+# mv to /etc/hosts
+shutil.copy(host_file, bak_file_name)
+shutil.move(tmp_file, host_file)
diff --git a/docker/image/alidata/lib/proc.sh b/docker/image/alidata/lib/proc.sh
new file mode 100644
index 00000000..40ddff93
--- /dev/null
+++ b/docker/image/alidata/lib/proc.sh
@@ -0,0 +1,40 @@
+# waitterm
+# wait TERM/INT signal.
+# see: http://veithen.github.io/2014/11/16/sigterm-propagation.html
+waitterm() {
+ local PID
+ # any process to block
+ tail -f /dev/null &
+ PID="$!"
+ # setup trap, could do nothing, or just kill the blocker
+ trap "kill -TERM ${PID}" TERM INT
+ # wait for signal, ignore wait exit code
+ wait "${PID}" || true
+ # clear trap
+ trap - TERM INT
+ # wait blocker, ignore blocker exit code
+ wait "${PID}" 2>/dev/null || true
+}
+
+# waittermpid "${PIDFILE}".
+# monitor process by pidfile && wait TERM/INT signal.
+# if the process disappeared, return 1, means exit with ERROR.
+# if TERM or INT signal received, return 0, means OK to exit.
+waittermpid() {
+ local PIDFILE PID do_run error
+ PIDFILE="${1?}"
+ do_run=true
+ error=0
+ trap "do_run=false" TERM INT
+ while "${do_run}" ; do
+ PID="$(cat "${PIDFILE}")"
+ if ! ps -p "${PID}" >/dev/null 2>&1 ; then
+ do_run=false
+ error=1
+ else
+ sleep 1
+ fi
+ done
+ trap - TERM INT
+ return "${error}"
+}
diff --git a/docker/run.sh b/docker/run.sh
new file mode 100644
index 00000000..7c56e2ba
--- /dev/null
+++ b/docker/run.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+
+function usage() {
+ echo "Usage:"
+ echo " run.sh [CONFIG]"
+ echo "example:"
+ echo " run.sh -e canal.instance.master.address=127.0.0.1:3306 \\"
+ echo " -e canal.instance.dbUsername=canal \\"
+ echo " -e canal.instance.dbPassword=canal \\"
+ echo " -e canal.instance.connectionCharset=UTF-8 \\"
+ echo " -e canal.instance.tsdb.enable=true \\"
+ echo " -e canal.instance.gtidon=false \\"
+ echo " -e canal.instance.filter.regex=.*\\..* "
+ exit
+}
+
+function check_port() {
+ local port=$1
+ local TL=$(which telnet)
+ if [ -f $TL ]; then
+ data=`echo quit | telnet 127.0.0.1 $port| grep -ic connected`
+ echo $data
+ return
+ fi
+
+ local NC=$(which nc)
+ if [ -f $NC ]; then
+ data=`nc -z -w 1 127.0.0.1 $port | grep -ic succeeded`
+ echo $data
+ return
+ fi
+ echo "0"
+ return
+}
+
+function getMyIp() {
+ case "`uname`" in
+ Darwin)
+ myip=`echo "show State:/Network/Global/IPv4" | scutil | grep PrimaryInterface | awk '{print $3}' | xargs ifconfig | grep inet | grep -v inet6 | awk '{print $2}'`
+ ;;
+ *)
+ myip=`ip route get 1 | awk '{print $NF;exit}'`
+ ;;
+ esac
+ echo $myip
+}
+
+NET_MODE=""
+case "`uname`" in
+ Darwin)
+ bin_abs_path=`cd $(dirname $0); pwd`
+ ;;
+ Linux)
+ bin_abs_path=$(readlink -f $(dirname $0))
+ NET_MODE="--net=host"
+ ;;
+ *)
+ NET_MODE="--net=host"
+ bin_abs_path=`cd $(dirname $0); pwd`
+ ;;
+esac
+BASE=${bin_abs_path}
+if [ $# -eq 0 ]; then
+ usage
+elif [ "$1" == "-h" ] ; then
+ usage
+elif [ "$1" == "help" ] ; then
+ usage
+fi
+
+DATA="$BASE/data"
+mkdir -p $DATA
+CONFIG=${@:1}
+#VOLUMNS="-v $DATA:/home/admin/canal-server/logs"
+PORTLIST="8000 8080 2222 11111"
+PORTS=""
+for PORT in $PORTLIST ; do
+ #exist=`check_port $PORT`
+ exist="0"
+ if [ "$exist" == "0" ]; then
+ PORTS="$PORTS -p $PORT:$PORT"
+ else
+ echo "port $PORT is used , pls check"
+ exit 1
+ fi
+done
+
+MEMORY="-m 4096m"
+LOCALHOST=`getMyIp`
+cmd="docker run -it -h $LOCALHOST $CONFIG --name=canal-server $VOLUMNS $NET_MODE $PORTS $MEMORY canal/canal-server"
+echo $cmd
+eval $cmd
\ No newline at end of file
diff --git a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java b/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java
index 29b96852..0f01cbd5 100644
--- a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java
+++ b/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java
@@ -32,7 +32,7 @@ public class MysqlConnector {
private String password;
private byte charsetNumber = 33;
- private String defaultSchema = "retl";
+ private String defaultSchema = "test";
private int soTimeout = 30 * 1000;
private int connTimeout = 5 * 1000;
private int receiveBufferSize = 16 * 1024;
diff --git a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java b/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java
index 6c2b9d4d..e640364f 100644
--- a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java
+++ b/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java
@@ -643,6 +643,9 @@ public class MysqlEventParser extends AbstractMysqlEventParser implements CanalE
throw new CanalParseException("command : 'show master status' has an error! pls check. you need (at least one of) the SUPER,REPLICATION CLIENT privilege(s) for this operation");
}
EntryPosition endPosition = new EntryPosition(fields.get(0), Long.valueOf(fields.get(1)));
+ if (isGTIDMode && fields.size() > 4) {
+ endPosition.setGtid(fields.get(4));
+ }
return endPosition;
} catch (IOException e) {
throw new CanalParseException("command : 'show master status' has an error!", e);