Технология Oracle Streams. Настраиваем потоки данных, экономим время и деньги Антон Пищулин global_names = true remote_archive_enable = true log_archive_dest_2 = 'SERVICE=site2 noregister reopen=300 template=C:\oracle\streams\site1_%t_%s_%r.arc' log_archive_dest_state_2 = 'enable' create user strmadm identified by strmadm; grant dba to strmadm; BEGIN DBMS_STREAMS_AUTH.grant_admin_privilege( grantee => 'strmadm', grant_privileges => true); commit; END; DECLARE TYPE tp IS TABLE OF VARCHAR2(20); tb tp := tp( –-Определяем схему и имя реплицируемого объекта 'hr.employees' ); BEGIN FOR i IN tb.FIRST .. tb.LAST LOOP --Включаем дополнительное логирование на таблицу на основе ключей DBMS_CAPTURE_ADM.prepare_table_instantiation( table_name => tb(i), supplemental_logging => 'keys'); END LOOP; END; global_names = true create user strmadm identified by strmadm; grant dba to strmadm; BEGIN DBMS_STREAMS_AUTH.grant_admin_privilege( grantee => 'strmadm', grant_privileges => true); commit; END; CREATE DATABASE LINK site1 CONNECT TO strmadm IDENTIFIED BY strmadm USING '(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) ) (CONNECT_DATA = (SID = site1) ) )'; DECLARE TYPE tp IS TABLE OF VARCHAR2(20); tb tp := tp( 'hr.employees' ); BEGIN FOR i IN tb.FIRST .. tb.LAST LOOP --Включаем дополнительное логирование на таблицу на основе ключей DBMS_CAPTURE_ADM.prepare_table_instantiation( table_name => tb(i), supplemental_logging => 'keys'); END LOOP; END; BEGIN DBMS_STREAMS_ADM.set_up_queue( --Таблица очереди сообщений queue_table => 'site1_queue_table', --Название очереди сообщений queue_name => 'site1_queue' ); END; BEGIN DBMS_CAPTUR_ADM.create_capture( --Название очереди сообщений queue_name => 'strmadm.site1_queue', --Название процесса захвата capture_name => 'capture_site1', -–Использовать dblink для настройки use_database_link => true, --База-источник source_database => 'site1' ); END; DECLARE TYPE tp IS TABLE OF VARCHAR2(20); tb tp := tp( 'hr.employees' ); BEGIN FOR i IN tb.FIRST .. tb.LAST LOOP --Создание положительного правила для таблицы DBMS_STREAMS_ADM.add_table_rules( table_name => tb(i), --Тип процесса streams streams_type => 'capture', --Название процесса streams streams_name => 'capture_site1', --Очередь сообщений streams queue_name => 'strmadm.site1_queue', --Включить dml операции include_dml => true, --Включить ddl операции include_ddl => true, --База-источник source_database => 'site1', --Положительное правило inclusion_rule => true ); END LOOP; END; DECLARE TYPE tp IS TABLE OF VARCHAR2(20); tb tp := tp( 'hr.employees' ); BEGIN FOR i IN tb.FIRST .. tb.LAST LOOP execute immediate 'alter table '||tb(i)||' add status_rec varchar2(1)'; execute immediate 'alter table '||tb(i)||' add status_dt date'; END LOOP; END; create or replace function site1_trans(evt in sys.anydata) --Получаем сообщение и отдаем его дальше после трансформации return sys.anydata is lcr sys.lcr$_row_record; lcr_val SYS.LCR$_ROW_LIST; obj_name varchar2(30); rc number; cmd_tp varchar2(10); st varchar2(1); dt date; begin --Если сообщение dml if evt.GetTypeName='SYS.LCR$_ROW_RECORD' then rc := evt.GetObject(lcr); obj_name := lcr.get_object_name(); --Определяем тип транзакции cmd_tp := lcr.get_command_type(); st := upper(substr(cmd_tp,1,1)); --Если удаление, то трансформируем в обновление if st = 'D' then lcr_val := lcr.get_values('OLD'); lcr.set_command_type('UPDATE'); lcr.set_values('OLD',lcr_val); dt := lcr.get_source_time(); --Заполняем сервисные поля lcr.ADD_COLUMN('NEW','status_dt',sys.anydata.convertdate(dt)); lcr.ADD_COLUMN('NEW','status_rec',sys.anydata.ConvertVarchar2(st)); return sys.anydata.convertobject(lcr); end if; --Заполняем сервисные поля lcr.ADD_COLUMN('NEW','status_dt',sys.anydata.convertdate(sysdate)); lcr.ADD_COLUMN('NEW','status_rec',sys.anydata.ConvertVarchar2(st)); return sys.anydata.convertobject(lcr); end if; return evt; end site1_trans; DECLARE TYPE tp IS TABLE OF VARCHAR2(50); tb tp := tp( 'hr.employees' ); BEGIN FOR i IN tb.FIRST .. tb.LAST LOOP DBMS_STREAMS_ADM.add_table_rules( table_name => tb(i), --Тип процесса streams streams_type => 'apply', --Название процесса streams streams_name => 'apply_site1', --Очередь сообщений streams queue_name => 'strmadm.site1_queue', --Включить dml операции include_dml => TRUE, --Включить ddl операции include_ddl => true, --База-источник source_database => 'site1', --Положительное правило inclusion_rule => true ); END LOOP; END; DECLARE TYPE tp IS TABLE OF VARCHAR2(50); tb tp := tp( 'hr.employees' ); BEGIN FOR i IN tb.FIRST .. tb.LAST LOOP DECLARE iscn NUMBER; --scn BEGIN --Получаем scn базы сервера-источника iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER@site1; --Устанавливаем scn на таблицу сервера-приемника DBMS_APPLY_ADM.set_table_instantiation_scn( source_object_name => tb(i), source_database_name => 'site1', instantiation_scn => iscn); END; END LOOP; END; DECLARE --Осуществляем выборку искомых правил CURSOR c1 (s1 varchar2) IS select c.rule_name from dba_streams_rules c where c.streams_type='APPLY' and c.rule_type = 'DML'; ss1 varchar2(200); BEGIN OPEN c1(ss1); LOOP begin FETCH c1 INTO ss1; EXIT WHEN c1%NOTFOUND; --Привязываем существующую функцию трансформации к правилам DBMS_STREAMS_ADM.set_rule_transform_function(ss1,'site1_trans'); exception when others then null; end; END LOOP; END; --Старт процессов захвата и применения изменений BEGIN dbms_apply_adm.start_apply('apply_site1'); dbms_capture_adm.start_capture('capture_site1'); END; update hr.employees t set t.first_name='anton' where t.employee_id=198; commit; --Попереключаем несколько раз журнальные логи, так как мы быстрее хотим дождаться результата теста alter system switch logfile; delete from hr.employees t where t.employee_id=199; commit; --Попереключаем несколько раз журнальные логи alter system switch logfile; insert into hr.employees select 207, e.first_name, e.last_name, 'letanton@mail.ru', e.phone_number, e.hire_date, e.job_id, e.salary, e.commission_pct, e.manager_id, e.department_id from hr.employees e where e.employee_id=198; commit; --Попереключаем несколько раз журнальные логи alter system switch logfile; --Просмотр состояния процесса захвата изменений Select * from dba_capture --Просмотр состояния процесса применения изменений select * from dba_apply; --Детализация ошибок процесса применения select * from dba_apply_error; --Мониторинг работы процесса захвата изменений SELECT c.CAPTURE_NAME, SUBSTR(s.PROGRAM,INSTR(s.PROGRAM,'(')+1,4) PROCESS_NAME, c.SID, c.SERIAL#, c.STATE, c.TOTAL_MESSAGES_CAPTURED, c.TOTAL_MESSAGES_ENQUEUED FROM V$STREAMS_CAPTURE c, V$SESSION s WHERE c.SID = s.SID AND c.SERIAL# = s.SERIAL#; --Мониторинг работы процесса применения изменений SELECT r.APPLY_NAME, DECODE(ap.APPLY_CAPTURED, 'YES','Captured LCRS', 'NO','User-enqueued messages','UNKNOWN') APPLY_CAPTURED, SUBSTR(s.PROGRAM,INSTR(s.PROGRAM,'(')+1,4) PROCESS_NAME, r.STATE, r.TOTAL_MESSAGES_DEQUEUED, R.TOTAL_MESSAGES_SPILLED FROM V$STREAMS_APPLY_READER r, V$SESSION s, DBA_APPLY ap WHERE r.SID = s.SID AND r.SERIAL# = s.SERIAL# AND r.APPLY_NAME = ap.APPLY_NAME; ----------------------------------------------------------------------------------------------------------------- WDS поможет. Установка операционных систем. Часть 1 Андрей Бирюков WDSUTIL /initialize-server /reminst:"<буква_диска>\<имя_папки>" WDSUTIL /Set-Server /AnswerClients:all WDSUTIL /Set-Server /UseDHCPPorts:no /DHCPoption60:yes WDSUTIL /Add-Image /ImageFile:<загрузочный_образ> /ImageType:boot WDSUTIL /add-image /ImageFile:<установочный_образ> /ImageType:install /ImageGroup:<имя_группы> WDSUTIL /? ----------------------------------------------------------------------------------------------------------------- Собираем свой дистрибутив с Calculate Linux Scratch Сергей Яремчук # mount | grep /mnt/scratch # layman -S; emerge calculate # eix-sync # emerge weechat # mount /dev/sda3 /usr/calculate/share/linux # calculate --iso # ls /usr/calculate/share/linux/ # calculate --rebuild # calculate -c/--configure # layman -S; emerge calculate # calculate -c -s CLDX # ls /usr/calculate/share/linux/ # "Определим наличие stage, portage" if(!$data{portage} && !defined $data{arg}{'vars'}){ printmes("\n"); printmes(gettext('To continue copy file')); printmes(" \"portage-YYYYMMDD.tar.bz2\"\n"); printmes(gettext('to directory')); printmes(" \"$data{portagepath}\".\n"); beep(); # Комментируем строку с exit # exit; } # mount | grep /mnt/builder # mount | grep /mnt/builder # diff /etc/make.conf /mnt/builder/etc/make.conf # calculate –l # calculate -D # calculate –m # calculate -p # calculate --iso -s cld cl-setup dns cl-setup --router --dnames <имена доменов> --range <диапазон ip> --net --dnsip dhcp # cl-unmask package1 package2 ----------------------------------------------------------------------------------------------------------------- Sun VirtualBox как персональная система виртуализации Алексей Бережной /usr/bin/VBoxManage startvm "test_xp" cd "c:\Program Files\Sun\xVM VirtualBox" VBoxManage.exe startvm "test_convert32" rpm -Uvh VirtualBox-3.0.4_50677_openSUSE111-1.i586.rpm ----------------------------------------------------------------------------------------------------------------- Один UPS на двоих. FreeBSD в домене Windows Рашид Ачилов # pw useradd upsadmin -d /usr/home/upsadmin -m -s /bin/sh -c "UPS administrator" -h - # su -l upsadmin # ssh-keygen2 -t dsa IdKey id_dsa_2048_a # Cmnd alias specification Cmnd_Alias SHUTDOWN = /sbin/shutdown Cmnd_Alias HALT = /sbin/halt Cmnd_Alias REBOOT = /sbin/reboot Cmnd_Alias IPFW = /sbin/ipfw # UPS remote command executor upsadmin ALL=(root) NOPASSWD: SHUTDOWN, NOPASSWD: HALT, NOPASSWD: REBOOT, NOPASSWD: IPFW # su -l upsadmin $ sudo ipfw sh PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/ sbin:/usr/local/bin:/usr/X11R6/bin:$HOME/bin; export PATH #!/bin/sh logger -i -p local6.info -t lansafe Shutdown started sudo shutdown -p now local6.* /var/log/powerdown !lansafe local6.* /var/log/powerdown Key winbox.pub echo "Testing connection on UNIX server..." plink.exe -ssh -P 22 -2 -i winbox.ppk upsadmin@192.168.1.1 ls -la с: cd \upsmgmt plink.exe -ssh -P 22 -2 -i winbox.ppk upsadmin@192.168.1.1 "powerdown" ----------------------------------------------------------------------------------------------------------------- Настройка Webacula. Веб-интерфейс к Bacula Сергей Яремчук $ sudo apt-get install mysql-server mysql-client $ sudo mysqladmin -u root password пароль $ sudo apt-get install bacula $ sudo nano /etc/bacula/bacula-dir.conf Catalog { Name = MyCatalog dbname = "bacula"; dbuser = "bacula"; dbpassword = "baculapass" } # Для вывода сообщений выводимых при выполнении заданий Messages: Messages { Name = Standard ... catalog = all, !skipped, !saved } $ sudo /etc/init.d/bacula-director restart $ netstat -l | grep bacula $ sudo apt-get install apache2 php5 libapache2-mod-php5 php5-mysql php5-gd $ sudo a2enmod php5 $ sudo a2enmod rewrite $ sudo mkdir /var/www/webacula $ wget -c http://dfn.dl.sourceforge.net/project/webacula/webacula/3.1/webacula-3.1.rc1.tar.gz $ sudo svn co http://webacula.svn.sourceforge.net/svnroot/webacula/trunk/webacula /var/www/webacula $ sudo chown -R www-data:www-data /var/www/webacula $ php5 /var/www/webacula/install/check_system_requirements.php $ cd /var/www/webacula/library $ sudo tar xzvf Zend-1.8.3.tar.gz $ sudo ./runme $ sudo nano /var/www/webacula/application/config.ini # Указываем учетную запись для подключения к базе bacula [general] db.adapter = PDO_MYSQL ; db.adapter = PDO_PGSQL db.config.host = localhost db.config.username = bacula db.config.password = baculapass db.config.dbname = bacula ; Часовой пояс http://www.php.net/timezones def.timezone = "Europe/Moscow" ; Webacula попытается определить язык автоматически, иначе снимаем комментарий ; locale = "ru" ; Каталог для временных файлов, директор должен иметь права на чтение tmpdir = "/tmp" ; Webacula, а если точнее, то веб-сервер должен иметь возможность запуска консоли управления bconsole. ; Предусмотрено два варианта реализации, через sudo и установкой прав. Подробности INSTALL, ; мы используем второй вариант ; bacula.sudo = "/usr/bin/sudo" ; Проверяем пути к файлам bacula.bconsole = "/usr/bin/bconsole" bacula.bconsolecmd = "-n -c /etc/bacula/bconsole.conf" ; Подключение к базе webacula [webacula] db.adapter = PDO_MYSQL ; db.adapter = PDO_PGSQL db.config.host = localhost db.config.username = wbuser db.config.password = wbpass db.config.dbname = webacula email.to_admin = root@localhost email.from = webacula@localhost $ sudo usermod -aG bacula www-data $ cat /etc/group | grep bacula $ sudo chown root:bacula /usr/bin/bconsole $ sudo chmod 750 /usr/bin/bconsole $ sudo chown root:bacula /etc/bacula/bconsole.conf $ sudo chmod 640 /etc/bacula/bconsole.conf $ sudo nano /etc/apache/sites-available/webacula Alias "/webacula" "/var/www/webacula/html" Options Indexes FollowSymLinks AllowOverride All Order deny,allow Allow from 127.0.0.1 Allow from 192.168.1.0/255.255.255.0 AuthType Basic AuthName "Webacula" AuthUserFile /etc/apache2/webacula.users Require valid-user $ sudo a2ensite webacula $ sudo htpasswd -c /etc/apache2/webacula.users admin $ cat /var/www/webacula/html/.htaccess php_flag magic_quotes_gpc off php_flag register_globals off RewriteEngine On RewriteBase /webacula RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php memory_limit = 32M max_execution_time = 300 $ sudo /etc/init.d/apache2 reload $ sudo apachectl -t -D DUMP_MODULES 2>&1 | grep rewrite $ mysql -u root -p mysql> CREATE USER 'wbuser'@'localhost' IDENTIFIED BY 'wbpass'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'webacula'@'localhost' WITH GRANT OPTION; mysql> FLUSH PRIVILEGES; mysql> quit $ sudo nano /var/www/webacula/install/webacula_mysql_create_database.sh db_user="wbuser" db_password="wbpass" host="localhost" ----------------------------------------------------------------------------------------------------------------- Создаем свой YouTube. Как обработать видео средствами веб-сервера Александр Майоров ffmpeg -v ffmpeg -i 1.3gp ffmpeg -i uploaded_file.avi output_file.flv ffmpeg -i uploaded_file.avi -ss 00:00:16.0 -b 512k output_file.flv ffmpeg -i inputfile.avi -s qcif -vcodec h263 -acodec aac -ac 1 -ar 8000 -r 25 -ab 32 -y outputfile.3gp ffmpeg -i input_clip.3gp -f avi -vcodec xvid -acodec mp3 -ar 22050 output_file.avi ffmpeg -i input_file.avi -vcodec h264 -threads 0 -r 25 -g 50 -b 500k -bt 500k -acodec mp3 -ar 44100 -ab 64k out_file.mp4 ffmpeg -i input_file.flv -vn -acodec copy soundtrack.mp3 ffmpeg -i input_file.avi -vn -acodec pcm_s16le -ar 44100 -ac 2 output_file.wav ffmpeg -i input_censored_file.flv -an -vcodec copy output_censored_file.flv ffmpeg -i video_input_file.flv -an -ss 30 -vframes 1 -s 340.180 -y -f mjpeg screenshot.jpg ffmpeg -i input_file.avi -an -pix_fmt rgb24 -ss 40 -vframes 64 -s 128.128 -loop_output 0 -f gif -y screenshot.gif ffmpeg -h tar -xjf ffmpeg-php.tbz2 $ cd ffmpeg-php/ $ phpize $ ./configure && make $ sudo make install $ php -i | grep ffmpeg PHP_WIN32 ZEND_WIN32 ZTS=1 ZEND_DEBUG=0 HAVE_LIBGD20=1 COMPILE_DL_FFMPEG /FORCE:MULTIPLE $(OutDir)\ffmpeg.dll #include "config.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #define _USE_32BIT_TIME_T 1 extension=php_ffmpeg.dll $FfmpegMovie = new ffmpeg_movie(String path_to_media, boolean persistent); $FfmpegMovie->getDuration(); $FfmpegMovie->getFrameCount(); $FfmpegMovie->getFrameRate(); $FfmpegMovie->getFilename(); $FfmpegMovie->getComment(); $FfmpegMovie->getTitle(); $FfmpegMovie->getFrameHeight(); $FfmpegMovie->getFrameWidth(); $FfmpegMovie->getAudioBitRate(); $FfmpegMovie->getFrameNumber(); $FfmpegMovie->getVideoCodec(); $FfmpegMovie->getAudioCodec(); $FfmpegMovie->getAudioChannels(); $FfmpegMovie->getFrame([Integer framenumber]); $Frame = new ffmpeg_frame(Resource gd_image); $Frame->getWidth(); $Frame->getHeight(); $Frame->resize(Integer width, Integer height [, Integer crop_top [, Integer crop_bottom [, Integercrop_left [, Integer crop_right ]]]]); $Frame->crop(Integer crop_top [, Integer crop_bottom [, Integer crop_left [, Integer crop_right ]]]); $Frame->toGDImage(); $Frame->addFrame(ffmpeg_frame frame_to_add); $Frame->getPresentationTimestamp(); $GifFile = new ffmpeg_animated_gif(String output_file_path, Integer width, Integer height, Integer frame_rate, [Integer loop_count]) $frame->addFrame(ffmpeg_frame frame_to_add); getFrame($number_of_frame ) ) { imagejpeg ( $Frame->toGDImage(), $path_to_image_file, $quality ); } } ?> post_max_size=256M ini_set('max_execution_time', 9000); php_value post_max_size 256M php_value upload_max_filesize 256M php_value max_execution_time 9000 php_value max_input_time 9000 -----------------------------------------------------------------------------------------------------------------