2008-08-16 53 views
7

Tôi có một công việc cron trên Ubuntu Hardy VPS chỉ có một nửa công việc và tôi không thể giải thích tại sao. Công việc là một kịch bản Ruby sử dụng mysqldump để sao lưu cơ sở dữ liệu MySQL được ứng dụng Rails sử dụng, sau đó được nén và tải lên máy chủ từ xa bằng SFTP.Tại sao Cron của tôi không hoạt động đúng?

Tệp gzip được tạo và sao chép thành công nhưng luôn bằng 0 byte. Tuy nhiên, nếu tôi chạy lệnh cron trực tiếp từ dòng lệnh nó hoạt động hoàn hảo.

Đây là công việc định kỳ:

PATH=/usr/bin 
10 3 * * * ruby /home/deploy/bin/datadump.rb 

Đây là datadump.rb:

#!/usr/bin/ruby 
require 'yaml' 
require 'logger' 
require 'rubygems' 
require 'net/ssh' 
require 'net/sftp' 

APP  = '/home/deploy/apps/myapp/current' 
LOGFILE = '/home/deploy/log/data.log' 
TIMESTAMP = '%Y%m%d-%H%M' 
TABLES  = 'table1 table2' 

log  = Logger.new(LOGFILE, 5, 10 * 1024) 
dump  = "myapp-#{Time.now.strftime(TIMESTAMP)}.sql.gz" 
ftpconfig = YAML::load(open('/home/deploy/apps/myapp/shared/config/sftp.yml')) 
config  = YAML::load(open(APP + '/config/database.yml'))['production'] 
cmd  = "mysqldump -u #{config['username']} -p#{config['password']} -h #{config['host']} --add-drop-table --add-locks --extended-insert --lock-tables #{config['database']} #{TABLES} | gzip -cf9 > #{dump}" 

log.info 'Getting ready to create a backup' 
`#{cmd}`  

# Strongspace 
log.info 'Backup created, starting the transfer to Strongspace' 
Net::SSH.start(ftpconfig['strongspace']['host'], ftpconfig['strongspace']['username'], ftpconfig['strongspace']['password']) do |ssh| 
    ssh.sftp.connect do |sftp| 
    sftp.open_handle("#{ftpconfig['strongspace']['dir']}/#{dump}", 'w') do |handle| 
     sftp.write(handle, open("#{dump}").read) 
    end 
    end 
end 
log.info 'Finished transferring backup to Strongspace' 

log.info 'Removing local file' 
cmd  = "rm -f #{dump}" 
log.debug "Executing: #{cmd}" 
`#{cmd}` 
log.info 'Local file removed' 

Tôi đã kiểm tra và kiểm tra lại tất cả các đường dẫn và họ đã đúng. Cả hai sftp.yml (thông tin đăng nhập SFTP) và cơ sở dữ liệu.yml (thông tin đăng nhập MySQL) được sở hữu bởi người dùng thực thi (triển khai) với quyền chỉ đọc cho người dùng đó (chmod 400). Tôi đang sử dụng phiên bản 1.1.x của net-ssh và net-sftp. Tôi biết họ không phải là người mới nhất, nhưng họ là những gì tôi quen thuộc vào lúc này.

Điều gì có thể khiến công việc cron thất bại?

Trả lời

2

Bạn có chắc tệp tạm thời đang được tạo chính xác khi chạy dưới dạng công việc định kỳ không? Thư mục làm việc cho tập lệnh của bạn sẽ được chỉ định trong biến môi trường HOME, hoặc mục nhập/etc/passwd cho người dùng đã cài đặt công việc cron. Nếu triển khai không có quyền ghi cho thư mục mà nó đang thực hiện, thì bạn có thể chỉ định đường dẫn tuyệt đối cho tệp kết xuất để khắc phục sự cố.

4

Có vẻ như PATH của bạn thiếu một vài thư mục, quan trọng nhất là /bin (đối với /bin/rm). Đây là những gì hệ thống của tôi /etc/crontab sử dụng:

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 
0

là cron gửi email với các bản ghi?

Nếu không, hãy đặt đầu ra của cron thành tệp nhật ký.

Đảm bảo chuyển hướng STDERR sang nhật ký.

8

Khi tập lệnh chạy tương tác một cách chính xác nhưng không chạy khi cron, vấn đề thường do cài đặt môi trường tại chỗ ... ví dụ PATH như được đề cập bởi @Ted Percival, nhưng có thể là các biến môi trường khác.

Điều này là do cron sẽ không gọi .bash_profile, .bashrc hoặc/etc/profile trước khi thực thi.

Cách tốt nhất để tránh điều này là đảm bảo bất kỳ tập lệnh nào được gọi bởi cron không đưa ra bất kỳ giả định nào về môi trường khi thực thi. Việc sắp tới này có thể đơn giản như bao gồm một vài dòng trong tập lệnh của bạn để đảm bảo môi trường được thiết lập đúng cách. Ví dụ: trong trường hợp của tôi, tôi có tất cả các cài đặt quan trọng trong/etc/profile (cho RHEL), vì vậy tôi sẽ bao gồm dòng sau trong bất kỳ tập lệnh nào được chạy theo cron:

source /etc/profile 
Các vấn đề liên quan