Notes about IT

Позднее Ctrl + ↑

Установка и настройка TeamCity под Ubuntu

Потребовалось поднять TeamCity для наших разработчиков. Вооружившись Google и терпением начал изучать различные мануалы.
Имеем Ubuntu Server 13.10 amd64, Apache 2, свежий TeamCity.

Распаковываем скаченный архив TeamCity в /var/www/teamcity
Меняем владельца:

sudo chown -R www-data /var/www/teamcity

Если хочется, то меняем порт на котором висит Teamcity:

sudo nano /var/www/teamcity/conf/server.xml

Создаем файл запуска:

touch /etc/init.d/teamcity

со следующим содержанием:

#!/bin/sh
# /etc/init.d/teamcity -  startup script for teamcity
export TEAMCITY_DATA_PATH="/var/www/teamcity/.BuildServer"

case $1 in
start)
 start-stop-daemon --start  -c www-data --exec /var/www/teamcity/bin/teamcity-server.sh start
;;

stop)
 start-stop-daemon --start -c www-data  --exec  /var/www/teamcity/bin/teamcity-server.sh stop
;;

esac

exit 0

Не забываем сделать его запускаемым

sudo chmod 0755 /etc/init.d/teamcity

Теперь регистрируем скрипт запуска:

sudo update-rc.d teamcity defaults

Запускаем вручную:

sudo /etc/init.d/teamcity start

Получим ошибку, если не установлена Java
Устанавливаем Java:

sudo apt-get purge openjdk*
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install openjdk-7-jdk

ИЛИ

sudo apt-get install oracle-java7-installer

Теперь все запустится на порту 8111 (по умолчанию), но хочется на 80 порту все иметь (проще). Для этого используем Apache в роли прокси.
Доустанавливаем необходимые модули:

sudo apt-get install libapache2-mod-proxy-html libapache2-mod-gnutls

Активируем модуль

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo /etc/init.d/apache2 restart

Создаем новый virtualHost в папке /etc/apache2/sites-available

sudo touch /etc/apache2/sites-available/teamcity.conf

Содержание примерно следующее:

<VirtualHost *:80>
    ServerAdmin admin@contoso.com
    ServerAlias teamcity.contoso.com
    ProxyRequests Off
    ProxyPreserveHost On
    ProxyVia full

    <proxy *>
    Order deny,allow
    Allow from all
    </proxy>

    ProxyPass        /  http://192.168.0.5:8111/
    ProxyPassReverse /  http://192.168.0.5:8111/

</VirtualHost>

где 192.168.0.5 сервер где крутится TeamCity
Активируем наш виртуальный хост:

sudo a2ensite teamcity.conf

И перезагружаем Apache:

sudo /etc/init.d/apache2 reload

Не забываем прописать на DNS сервере A-запись

192.168.0.5 A teamcity.contoso.com

Разворачивание из бекапа


Если бекап TeamCity_Backup_20140725_170732.zip
Для того, что бы восстановить (при обновлении или еще после чего) следуем по шагам:

  1. останавливаем сервис Teamcity:
/etc/init.d/teamcity stop
  1. Копируем в корень TeamCity файл database.hsqldb.properties.dist из /var/www/teamcity/.BuildServer/config (считаем, что БД у нас HSQLDB)
  2. Удаляем все из /var/www/teamcity/.BuildServer/config/ и /var/www/teamcity/.BuildServer/system/
  3. Идем в папку bin:
cd /var/www/teamcity/bin
  1. Запускаем восстановление:
./maintainDB.sh restore -F TeamCity_Backup_20140725_170732.zip -A /var/www/teamcity/.BuildServer/ -T /var/www/teamcity/database.hsqldb.properties.dist

Если хочет получить переменную JAVA_HOME, то даем так:

export JAVA_HOME=/usr/lib/jvm/java-7-oracle
  1. Запускаем сервис TeamCity
/etc/init.d/teamcity start
  1. Заходим в веб-морду и следуем инструкциям
2013   nix

phpmyadmin — mcrypt extension is missing

После установки apache/nginx и заливки PHPMyAdmin в интерфейсе последнего можно обнаружить ошибку The mcrypt extension is missing. Please check your PHP configuration.

Решение есть:

sudo apt-get install php5-mcrypt
cd /etc/php5/apache2/conf.d
sudo ln -s ../../conf.d/mcrypt.ini 30-mcrypt.ini
sudo service apache2 restart

или

sudo apt-get install php5-mcrypt
mv -i /etc/php5/conf.d/mcrypt.ini /etc/php5/mods-available/
sudo php5enmod mcrypt
sudo service apache2 restart
2013   nix   phpmyadmin

Полезные SQL запросы для WordPress

Смена пароля

Забыли свой пароль администратора в блоге? Не беда, его легко можно сменить следующим запросом:

UPDATE wp_users SET user_pass = MD5('12345') WHERE ID=1;

Паролем тут будет «12345». Можно сменить пароль и для любого другого юзера в блоге, достаточно поменять в запросе ID, который у админа всегда равен 1. Можно также использовать запрос и с указанием конкретного логина:

UPDATE wp_users SET user_pass = MD5('12345') WHERE user_login = 'admin';

Смена логина администратора

По умолчанию в WordPress нельзя изменить логин администратора, который всегда будет «admin». Это не слишком правильно с точки зрения безопасности, так как дает возможность злоумышленникам перебирать пароли для известного им имени администратора. Изменить логин админа можно запросом:

UPDATE wp_users SET user_login = 'test' WHERE user_login = 'admin';

Где «test» это новый логин администратора блога.

Смена урлов для WordPress и сайта

Обычно адрес WordPress и адрес сайта в настройках блога совпадают, но иногда пользователи хотят вынести блог в отдельную папку, для этого они меняют адрес сайта или адрес WordPress, не меняя при этом физическое расположение файлов движка. В результате они не могут больше войти в админку блога. Исправить данную ситуацию можно через запрос:

UPDATE wp_options SET option_value = 'http://www.testwp.ru/' WHERE option_name = 'home' OR option_name = 'siteurl';

Где ’http://www.testwp.ru/' это актуальный урл вашего сайта.

Удаление спам-комментариев

Многим лениво править файлы движка, чтобы использовать мою защиту от спама. Ведь Akismet сейчас ловит почти весь приходящий спам и мало кого радует перспектива применять хак при выходе каждой новой версии WordPress. В результате у блогеров скапливаются тысячи спам-комментариев, очищать которые вручную гиблое дело. Маленький запрос удалит все комментарии, помеченные в блоге как спам:

DELETE FROM wp_comments WHERE comment_approved = 0

Изменение GUID

При смене домена у сайта необходимо поменять значение GUID (globally unique identifier) в таблице wp_posts. Простой смены адреса сайта и WordPress в настройках блога недостаточно! GUID необходимо менять даже при переезде с localhost к хостеру.

UPDATE wp_posts SET guid = REPLACE (guid, 'http://www.oldblog.ru', 'http://www.newblog.ru');

Формально у вас все будет работать и без этого запроса, но смена GUID необходима, чтобы WordPress мог правильно перенаправлять с неправильных урлов записей на правильные.

Изменение URL в записях

Таким запросом можно поменять все ссылки в ваших записях на корректные.

UPDATE wp_posts SET post_content = REPLACE (post_content, 'http://www.oldblog.ru', 'http://www.newblog.ru');

Необходимо при переносе блога на новый домен, при смене урла сайта, на который вы часто ссылались и т. д. Менять можно не только ссылку, но и любой другой текст в ваших записях.

Изменение автора записей

Чтобы изменить авторство записей с одного пользователя на другого используйте запрос:

UPDATE wp_posts SET post_author=New_Author_ID WHERE post_author=Old_Author_ID;

Где New_Author_ID это ID нового автора, а Old_Author_ID это ID старого автора.

Удаление ревизий записей

Ревизии вещь хорошая, но очень уж они быстро забивают базу данных своими копиями. Чтобы разом прибить все ревизии используйте запрос:

DELETE a,b,c FROM wp_posts a
LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id)
LEFT JOIN wp_postmeta c ON (a.ID = c.post_id)
WHERE a.post_type = 'revision'

Данный запрос не только удалит ненужные ревизии, но и всю meta-информацию, которая к ним привязана.

Удаление лишних Meta

Многие плагины хранят нужную им информацию в таблице wp_postmeta. При удалении плагинов большинство из них не чистит за собой эту информацию, вручную удалить ее можно запросом:

DELETE FROM wp_postmeta WHERE meta_key = 'your-meta-key';

Где your-meta-key это и есть удаляемый meta-ключ. Например, плагин Another WordPress Meta Plugin хранит свою информацию в meta-ключе под названием «description». При удалении этого плагина вся введенная информация остается в базе данных и удалить ее можно запросом:

DELETE FROM wp_postmeta WHERE meta_key = 'description';

Вывод неиспользуемых Meta

В продолжение запроса удаления ненужных meta. Данный запрос выведет все неиспользуемые meta-ключи в вашем блоге.

SELECT *
FROM wp_postmeta pm
LEFT JOIN wp_posts wp ON wp.ID = pm.post_id
WHERE wp.ID IS NULL

Только вот небольшая оговорка — это будет список тех meta, которые не содержат информации. Если вы пользовались плагином, вводили информацию, а потом удалили плагин, то его meta-ключи тут выведены не будут.

Собираем Email’ы комментаторов

Можно собрать базу имейлов из комментаторов вашего блога:

SELECT DISTINCT comment_author_email FROM wp_comments;

Таким образом, вы получите список имейлов ваших комментаторов (без дубликатов). Можно использовать в качестве базы для новостных рассылок заинтересованным посетителям. Правда, пользоваться такой базой надо крайне осторожно, люди не хотят получать лишний спам с каждого блога, где они оставили когда-то свой комментарий.

Удаление всех пингбеков

Иногда количество пингбеков слишком велико, их можно удалить все сразу:

DELETE FROM wp_comments WHERE comment_type = 'pingback';

Вывод неиспользуемых тегов

При удалении записи в блоге удаляется только сама запись. Теги же переходят в разряд неиспользуемых (если они были присвоены только этой одной удаляемой записи). Вывести список неиспользуемых тегов можно запросом:

SELECT * FROM wp_terms wt INNER JOIN wp_term_taxonomy wtt ON wt.term_id=wtt.term_id WHERE wtt.taxonomy='post_tag' AND wtt.COUNT=0;

Оставлять такие неиспользуемые теги или удалять решать только вам.

Деактивация всех плагинов сразу

Иногда при установке какого-либо плагина может возникнуть ситуация, при которой вы уже не можете войти в админку блога. Удалить некорректный плагин можно по ftp, а можно просто деактивировать все плагины, войти в админку и уже там удалить нужный плагин:

UPDATE wp_options SET option_value = '' WHERE option_name = 'active_plugins';

Удаление всех тегов

Уж не знаю зачем, но возможно вам понадобится удалить все теги сразу. Для этого используйте запрос:

DELETE a,b,c
FROM
wp_terms AS a
LEFT JOIN wp_term_taxonomy AS c ON a.term_id = c.term_id
LEFT JOIN wp_term_relationships AS b ON b.term_taxonomy_id = c.term_taxonomy_id
WHERE (
c.taxonomy = 'post_tag' AND
c.COUNT = 0
);

Закрытие комментирования старых записей

На буржуйских сайтах часто рекомендуют закрывать комментарии ко всем старым записям, чтобы избежать ненужного спама. Для этого используйте запрос:

UPDATE wp_posts SET comment_status = 'closed' WHERE post_date &lt; '2011-01-01' AND post_status = 'publish';

Комментирование будет закрыто для всех записей, опубликованных раньше даты «2011-01-01». Повторюсь опять, проще не закрывать комментирование, а закрыть саму возможность автоматического спама.

Изменение урла сайта комментатора

Данным кодом можно изменить ссылку на домашний сайт комментатора:

UPDATE wp_comments SET comment_author_url = REPLACE( comment_author_url, 'http://www.oldblog.ru', 'http://www.newblog.ru' );

Бывает очень полезно, когда известный вам сайт комментатора вдруг начинает вести на порно-ресурс вследствие взлома.

Удаление комментариев по маске

Можно удалить комментарии со ссылками, содержащими определенное стоп-слово:

DELETE FROM wp_comments WHERE comment_author_url LIKE "%porno%";

При этом будут удалены все комментарии, у которых в качестве ссылки на домашний сайт комментатора указаны урлы со словом «porno».

Частные случаи замены текста

Замену текста в базе можно использовать совершенно для разных вещей. Например, если вы оформляли внешние ссылки в вашем блоге через rel=«nofollow», то можно автозаменой сделать все эти ссылки, открываемыми в новом окне браузера:

UPDATE wp_posts
SET post_content = REPLACE (post_content, 'rel="nofollow"', 'target="_blank" rel="nofollow"');

А можно наоборот, сделать все открываемые в новом окне браузера ссылки закрытыми через rel=«nofollow»:

UPDATE wp_posts
SET post_content = REPLACE (post_content, 'target="_blank"', 'target="_blank" rel="nofollow"');

Управление комментированием

Открыть все записи для комментирования:

UPDATE wp_posts SET comment_status = 'open';<code>
Закрыть все записи для комментирования:
<code>UPDATE wp_posts SET comment_status = 'closed';<code>
Открыть комментирование только для зарегистрированных пользователей:
<code>UPDATE wp_posts SET comment_status = 'registered_only';</code>

((http://www.wordpressplugins.ru www.wordpressplugins.ru))
2013   sql   wordpress

Подобие IIS Web farm на Mikrotik

Задача: Заменить IIS Web farm на mikriotik.
Минус реализации: Если на одном из серверов упадет веб-сервер, то этот сервер не исключается, т. к. используются icmp запросы.

IP — Web Proxy
Chack «Enable»
Src. Address: xxx.xxx.xxx.xxx (external mikrotik)
Port: 8080
Cache Administrator: webmaster
Max. Cache Size: unlimited KiB
Uncheck «Cache On Disk»
Max. Client Connections: 600
Max. Server Connections: 600
Max Fresh Time: 00:00:01
Uncheck «Serialize Connections» & «Always From Cache»
Cache Hit DSCP (TOS): 4
Cache Drive: system

IP — Web Proxy — Access
Add
Dst. Port: 80
Action: allow
Comment: Enable HTTP Connection

Add
Dst. Port: 23-25
Action: deny
Comment: block telnet & spam e-mail relaying

DNS — Static — min 2 servers
Add
Name: example.contos.com
Address: xxx.xxx.xxx.xxx (internal server)
TTL: 00:00:05

Tools — Netwatch — min 2 servers
Add
Host
Host: xxx.xxx.xxx.xxx (internal server)
Interval: 00:00:05
Timeout: 100 ms
Status: up
Up
/ip dns static enable numbers=[find where address=xxx.xxx.xxx.xxx (internal server)]
Down
/ip dns static disable numbers=[find where address=xxx.xxx.xxx.xxx (internal server)]

IP — Firewall — Nat
Add
General
Chain: dstnat
Dst: Address: xxx.xxx.xxx.xxx (external mikrotik)
Protokol: 6 (tcp)
dst. Port: 80
Action
Action: redirect
To Ports: 8080

2013   iis   mikrotik

Установка VMWare Tools в Ubuntu Server под ESXi

VMWare классная платформа с которой удобно работать. К сожалению, что бы гостевые системы работали шустрее и позволить VMWare выполнять определенные функции (перезагрузка, выключение и пр.) необходимо накатить VMWare Tools. На Windows гостевые ОС установка тривиальна, однако под Linux для некоторых это действие может вызвать ступор.
Итак, у вас есть машина с развернутой ESXi и уже созданной виртуальной машиной, например, Ubuntu Server 13.10.

Во-первых, нужно смонтировать образ VMWare Tools в виртуальный привод (VM -> Guest -> Install/Upgrade VMWare Tools).
А теперь монтируем в нашей гостевой системе:

cd /mnt
mkdir cdrom
mount /dev/cdrom /mnt/cdrom/
cd /mnt/cdrom

Теперь заходим в папку примонтированого CD, смотрим что внутри и копируем во временную папку нашей машины.

ls -al
cp VM*.gz /tmp/

Переходим во временную папку и разархивируем файл:

cd /tmp
tar xvzf VM*.gz

Переходим в папку и запускаем установку:

cd vmware-tools-distrib/
./vmware-install.pl

Отвечаем на все вопросы (можно жать везде Enter).
Ну все, все должно было встать, теперь делаем перезагрузку виртуальной системы:

reboot

и используем нашу систему.

2013   esxi   nix

Добавляем в Sublime Text 2 подсветку PowerShell

Что бы в Sublime Text 2 появилась подсветка кода PowerShell необходимо:

  1. Скачать, если все еще не пользуетесь, замечательный текстовый редактор Sublime Text 2.
  1. Установить, если все еще не стоит, Sublime Package Control.
  1. Запустить Sublime Text 2 и открыть консоль CTRL + `
  1. Вставить код с сайта или избрать путь ленивых и взять код ниже:
    код для ST2
import urllib2,os; pf='Package Control.sublime-package'; ipp = sublime.installed_packages_path(); os.makedirs( ipp ) if not os.path.exists(ipp) else None; urllib2.install_opener( urllib2.build_opener( urllib2.ProxyHandler( ))); open( os.path.join( ipp, pf), 'wb' ).write( urllib2.urlopen( 'http://sublime.wbond.net/' +pf.replace( ' ','%20' )).read()); print( 'Please restart Sublime Text to finish installation')

код для ST3

import urllib.request,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404' + 'e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)
  1. Открыть ’Command Pallete’ CTRL + Shift + P
  1. Выбрать ’Package Control: Add Repository’.
  1. Вставить следующий URL:
https://github.com/SublimeText/PowerShell.git
  1. Снова открыть ’Command Pallete’ и выбрать ’Package Control: Install Package’. Написать Powershell и выбрать ’PowerShellUtils’.
  1. Теперь у нас в меню ’View — Syntax’ появился PowerShell V2.
2013   sublime

Создание персональных папок для пользователей домена

Простенький скрипт, точнее три его разновидности, для случая, когда необходимо создать папки для ряда пользователей на файловом сервере при условии, что названия папок будут совпадать с именами пользователей и эти пользователи будут иметь определенный уровень доступа к этим (своим) папкам. Все это может создаваться внутри определенной папки непосредственно на сервере или через сеть в общей папке по UNC пути.

Первый пример использует дополнительный модуль ActiveDirectory и предназначен для случая, когда пользователи находятся в каком-либо OU в AD:

#
# PowerShell Script.
# Creates home folders for users from an OU in AD and set permissions.
# Prepared by Alexander Lipovetskiy. August 2013.
#

cls

# We need the AD module for this first
Import-Module ActiveDirectory

# A folder or share where home folders must be created.
$Dir = "D:\Users"
# or $Dir = "\\server\share\"

# Path to an OU with users.
$Users = Get-ADUser -Filter * -SearchBase "OU=Users,OU=Muhosransk,DC=domain,DC=com"

# Creating folders and setting permissions.
foreach ($User in $Users) {
    $User = $User.Name
    $Path = New-Item -ItemType Directory -Path $Dir -Name $User
    $Args = New-Object  system.security.accesscontrol.filesystemaccessrule($User,"Modify, Synchronize", "ContainerInherit, ObjectInherit", "None", "Allow")
    $ACL = Get-Acl $Path
    $ACL.SetAccessRule($Args)
    Set-Acl $Path $ACL
    }

Второй пример обрабатывает список пользователей, находящийся в текстовом файле:

#
# PowerShell Script.
# Creates home folders for a list of users and set permissions.
# Prepared by Alexander Lipovetskiy. August 2013.
#

cls

# A folder or share where home folders must be created.
$Dir = "D:\Users"
# or $Dir = "\\server\share\"

# Path to a text file with users.
$Users = Get-Content "$home\users.txt"

# Creating folders and setting permissions.
foreach ($User in $Users) {
    $Path = New-Item -ItemType Directory -Path $Dir -Name $User
    $Args = New-Object  system.security.accesscontrol.filesystemaccessrule($User,"Modify, Synchronize", "ContainerInherit, ObjectInherit", "None", "Allow")
    $ACL = Get-Acl $Path
    $ACL.SetAccessRule($Args)
    Set-Acl $Path $ACL
    }

В данных примерах устанавливаются не полные права, а «Modify, Synchronize» не дающие возможности пользователям менять security permissions и становиться владельцами папок. Конечно все это можно поменять на FullControl или что-либо другое. Также в примерах установлено наследование разрешений подпапками и файлами.

Третий пример, для случая, когда папки создаются для членов АД группы и прописываются им как домашние директории:

#
# PowerShell Script.
# Creates home folders for a list of users and set permissions.
# Prepared by Alexander Lipovetskiy. August 2013.
#

cls

# We need the AD module for this first
Import-Module ActiveDirectory

# A folder or share where home folders must be created.
$Dir = "D:\Users"
# or $Dir = "\\server\share\"

# Extract group members.
$Users = Get-ADGroupMember -Identity "Groupname" -Recursive

# Creating folders and setting permissions.
foreach ($User in $Users) {
    $Path = New-Item -ItemType Directory -Path $Dir -Name $User
    $Args = New-Object  system.security.accesscontrol.filesystemaccessrule($User,"Modify, Synchronize", "ContainerInherit, ObjectInherit", "None", "Allow")
    $ACL = Get-Acl $Path
    $ACL.SetAccessRule($Args)
    Set-Acl $Path $ACL
    Set-ADUser -Identity $User -HomeDrive "Z:" -HomeDirectory "$Dir$User"
    }

habrahabr.ru

2013   windows

Переносим Windows системы из физической в виртуальную среду

Практически каждый раз, когда я рассказываю о виртуализации, люди задают один и тот же вопрос. Как переносить все то, что нажито непосильным трудом в систему виртуализации? Не хочется ведь настраивать все заново.

Обычно я рекомендую несколько вариантов:
Воспользоваться SCVMM и обязательно прочитать вот эту статью о миграции P2V и посмотреть вебкаст о миграции в SCVMM

Применить для миграции VSMT и ADSк

Взять на вооружение инструменты третьих фирм, такие как Paragon Vitalization Manager или Acronis True Image Echo Server

Сегодня у нас появился еще один бесплатный способ сделать то, что нужно, играючи. Компания Sysinternals, ныне входящая в состав Microsoft, выпустила утилиту disk2vhd, которая позволяет конвертировать Windows системы в VHD файлы, не прерывая их работы. Поддерживаются все клиентские и серверные системы, начиная с Windows XP SP2 и Windows Server 2003. Затем VHD файлы можно подключить к системам виртуализации, таким как Hyper-V, Virtual Server или Virtual PC и запустить перенесенные системы. Работает это проще простого. Скачиваем утилиту disk2vhd или запускаем disk2vhd прямо из интернет в той системе, которую собираемся мигрировать. Выбираем, какие разделы конвертировать в vhd, и, если есть необходимость, продолжаем работать в системе, ожидая завершения процесса.

Я решил конвертировать в VHD только раздел MAIN, находящийся на первом физическом диске моей системы. Именно с него загружается система и на нем стоят все нужные приложения.

Процесс конвертации системного раздела Windows 7 занял примерно 40 минут. Вероятно, это случилось потому, что результирующий VHD файл писался на медленный внешний USB накопитель. Во время работы disk2vhd я писал эту заметку и работал с другими приложениями в мигрируемой системе. Каких-либо неудобств замечено не было. Для ускорения процесса рекомендуется записывать получившийся VHD на диск, не участвующий в конвертировании.

После получения VHD диска копируем его в систему виртуализации и создаем новую виртуальную машину. Подсоединяем к ней наш VHD, настраиваем нужные параметры, такие как виртуальная память, и количество сетевых интерфейсов.

Сразу же после первого запуска на новом месте, из виртуальной машины автоматически удаляются все ненужные физические устройства и устанавливаются все необходимые виртуальные. Перезагрузите виртуальную машину и наслаждайтесь результатом.

Обратите внимание, что расположение NTFS раздела MAIN, который мы переносили, абсолютно точно скопировано в виртуальный VHD. Совпадает все вплоть до неразмеченного места, на которое при желании можно расширить NTFS раздел MAIN.

Единственной проблемой, которую я заметил, является несовпадение Windows Experience Index реальной системе и невозможность его пересчитать в виртуальной. Думаю, что это не критично.

Как видите, ничего сложного в процессе переноса работающих ОС в системы виртуализации от Microsoft нет.

Удачных вам проектов миграции!
Andrey Beshkov

2013   hyper-v   windows

Полезные скрипты T-SQL

Много различных T-SQL скриптов

что сейчас происходит на сервере

select session_id, status, wait_type, command, last_wait_type, percent_complete, qt.text, total_elapsed_time/1000 as [total_elapsed_time, сек],
       wait_time/1000 as [wait_time, сек], (total_elapsed_time - wait_time)/1000 as [work_time, сек]
  from sys.dm_exec_requests as qs
  CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
  where session_id >= 50 and session_id <> @@spid
  order by 1;

что сейчас происходит на сервере (подробнее)

select *
  from sys.sysprocesses where spid > 50 and spid <> @@spid and status <> 'sleeping'
  order by spid, ecid;

фрагментированные индексы

SELECT TOP 100
       DatbaseName = DB_NAME(),
       TableName = OBJECT_NAME(s.[object_id]),
       IndexName = i.name,
       i.type_desc,
       [Fragmentation %] = ROUND(avg_fragmentation_in_percent,2),
       page_count,
       partition_number,
       'alter index [' + i.name + '] on [' + sh.name + '].['+ OBJECT_NAME(s.[object_id]) + '] REBUILD' + case
                                                                                                           when p.data_space_id is not null then ' PARTITION = '+convert(varchar(100),partition_number)
                                                                                                           else ''
                                                                                                         end + ' with(maxdop = 1,  SORT_IN_TEMPDB = on)' [sql]
  FROM sys.dm_db_index_physical_stats(db_id(),null, null, null, null) s
  INNER JOIN sys.indexes as i ON s.[object_id] = i.[object_id] AND
                                 s.index_id = i.index_id
  left join sys.partition_schemes as p on i.data_space_id = p.data_space_id
  left join sys.objects o on  s.[object_id] = o.[object_id]
  left join sys.schemas as sh on sh.[schema_id] = o.[schema_id]
  WHERE s.database_id = DB_ID() AND
        i.name IS NOT NULL AND
        OBJECTPROPERTY(s.[object_id], 'IsMsShipped') = 0 and
        page_count > 100 and
        avg_fragmentation_in_percent > 10
  ORDER BY 4,page_count;

задержки

SELECT TOP 10
 [Wait type] = wait_type,
 [Wait time (s)] = wait_time_ms / 1000,
 [% waiting] = CONVERT(DECIMAL(12,2), wait_time_ms * 100.0 
               / SUM(wait_time_ms) OVER())
  FROM sys.dm_os_wait_stats
  WHERE wait_type NOT LIKE '%SLEEP%' 
  ORDER BY wait_time_ms DESC;

итоговое число отсутствующих индексов для каждой базы данных

SELECT [DatabaseName] = DB_NAME(database_id),
       [Number Indexes Missing] = count(*) 
  FROM sys.dm_db_missing_index_details
  GROUP BY DB_NAME(database_id)
  ORDER BY 2 DESC;

Отсутствующие индексы, вызывающие издержки

SELECT TOP 10 
       [Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0),
       avg_user_impact,
       TableName = statement,
       [EqualityUsage] = equality_columns,
       [InequalityUsage] = inequality_columns,
       [Include Cloumns] = included_columns
  FROM sys.dm_db_missing_index_groups g 
  INNER JOIN sys.dm_db_missing_index_group_stats s ON s.group_handle = g.index_group_handle 
  INNER JOIN sys.dm_db_missing_index_details d ON d.index_handle = g.index_handle
  WHERE database_id = DB_ID()
  ORDER BY [Total Cost] DESC;

Неиспользуемые индексы

SELECT DatabaseName = DB_NAME(),
       TableName = OBJECT_NAME(s.[object_id]),
       IndexName = i.name,
       user_updates,
       system_updates,
       'EXEC sp_rename ''[dbo].['+OBJECT_NAME(s.[object_id])+'].['+i.name+']'',''disable_'+i.name+''',''INDEX''' as Rename,
       'ALTER INDEX '+i.name+' ON '+OBJECT_NAME(s.[object_id])+' DISABLE' as [Disable]
  FROM sys.dm_db_index_usage_stats s 
  INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND
                              s.index_id = i.index_id
  WHERE s.database_id = DB_ID() AND
        OBJECTPROPERTY(s.[object_id], 'IsMsShipped') = 0 AND
        user_seeks = 0     AND
        user_scans = 0     AND
        user_lookups = 0   AND
        i.is_disabled <> 1 AND
        i.is_primary_key <> 1
  order by user_updates + system_updates desc;

Запросы с высокими издержками на ввод-вывод

SELECT TOP 10
       [Average IO] = (total_logical_reads + total_logical_writes) / qs.execution_count,
       [Total IO] = (total_logical_reads + total_logical_writes),
       [Execution count] = qs.execution_count,
       [Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2, (CASE
                                                                               WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 
                                                                               ELSE qs.statement_end_offset
                                                                             END - qs.statement_start_offset)/2),
       [Parent Query] = qt.text,
       [DatabaseName] = DB_NAME(qt.dbid)
  FROM sys.dm_exec_query_stats qs
  CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
  ORDER BY [Average IO] DESC;

Запросы с высоким использованием ресурсов ЦП

SELECT TOP 10
       [Average CPU used] = total_worker_time / qs.execution_count,
       [Total CPU used] = total_worker_time,
       [Execution count] = qs.execution_count,
       [Individual Query] = SUBSTRING(qt.text,qs.statement_start_offset/2, 
         (CASE
            WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 
            ELSE qs.statement_end_offset
          END - qs.statement_start_offset)/2),
       [Parent Query] = qt.text,
       [DatabaseName] = DB_NAME(qt.dbid)
  FROM sys.dm_exec_query_stats qs
  CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
  ORDER BY [Average CPU used] DESC;

Запросы, страдающие от блокировки

SELECT TOP 10
       [Average Time Blocked] = (total_elapsed_time - total_worker_time) / qs.execution_count,
       [Total Time Blocked] = total_elapsed_time - total_worker_time,
       [Execution count] = qs.execution_count,
       [Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2, 
         (CASE
            WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 
            ELSE qs.statement_end_offset
          END - qs.statement_start_offset)/2),
       [Parent Query] = qt.text,
       [DatabaseName] = DB_NAME(qt.dbid)
  FROM sys.dm_exec_query_stats qs
  CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
  ORDER BY [Average Time Blocked] DESC;

нагрузку на подсистему ввода-вывода

select top 5 
    (total_logical_reads/execution_count) as avg_logical_reads,
    (total_logical_writes/execution_count) as avg_logical_writes,
    (total_physical_reads/execution_count) as avg_phys_reads,
     Execution_count, 
    statement_start_offset as stmt_start_offset, 
    plan_handle,
    qt.text
from sys.dm_exec_query_stats  qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
order by  (total_logical_reads + total_logical_writes) Desc;

какой процессор что делает

SELECT DB_NAME(ISNULL(s.dbid,1)) AS [Имя базы данных],
       c.session_id AS [ID сессии],
       t.scheduler_id AS [Номер процессора],
       s.text AS [Текст SQL-запроса]
  FROM sys.dm_exec_connections AS c
  CROSS APPLY master.sys.dm_exec_sql_text(c.most_recent_sql_handle) AS s
  JOIN sys.dm_os_tasks t ON t.session_id = c.session_id AND
                            t.task_state = 'RUNNING' AND
                            ISNULL(s.dbid,1) > 4
  ORDER BY c.session_id DESC;

контроль «несжатости»

SELECT tbl.name,
       i.name,
       p.partition_number AS [PartitionNumber],
       p.data_compression_desc AS [DataCompression],
       p.rows  AS [RowCount]
  FROM sys.tables AS tbl
  LEFT JOIN sys.indexes AS i ON (i.index_id > 0 and i.is_hypothetical = 0) AND (i.object_id=tbl.object_id)
  INNER JOIN sys.partitions AS p ON p.object_id = CAST(tbl.object_id AS int) AND
                                    p.index_id = CAST(i.index_id AS int)
  where p.data_compression_desc <> 'PAGE' and
        p.rows >= 1000000
  order by p.rows desc, 3;

статистика по операциям в БД

SELECT t.name AS [TableName],
       fi.page_count AS [Pages],
       fi.record_count AS [Rows],
       CAST(fi.avg_record_size_in_bytes AS int) AS [AverageRecordBytes],
       CAST(fi.avg_fragmentation_in_percent AS int) AS [AverageFragmentationPercent],
       SUM(iop.leaf_insert_count) AS [Inserts],
       SUM(iop.leaf_delete_count) AS [Deletes],
       SUM(iop.leaf_update_count) AS [Updates],
       SUM(iop.row_lock_count) AS [RowLocks],
       SUM(iop.page_lock_count) AS [PageLocks]
  FROM sys.dm_db_index_operational_stats(DB_ID(),NULL,NULL,NULL) AS iop
  JOIN sys.indexes AS i ON iop.index_id = i.index_id AND
                           iop.object_id = i.object_id
  JOIN sys.tables AS t ON i.object_id = t.object_id AND
                          i.type_desc IN ('CLUSTERED', 'HEAP')
  JOIN sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'SAMPLED') AS fi ON fi.object_id=CAST(t.object_id AS int) AND
                                                                                     fi.index_id=CAST(i.index_id AS int)
  GROUP BY t.name, fi.page_count, fi.record_count, fi.avg_record_size_in_bytes, fi.avg_fragmentation_in_percent
  ORDER BY [RowLocks] desc;

дата обновления статистики

SELECT STATS_DATE(t1.object_id, stats_id), 'UPDATE STATISTICS [' + object_name(t1.object_id) + ']([' + t1.name + ']) WITH FULLSCAN',
       i1.rows
  FROM sys.stats as t1
  inner join sys.sysobjects as t2 on t1.object_id = t2.id
  left join sysindexes as i1 on i1.id = t1.object_id and
                                i1.indid = 1
  where xtype = 'U' and
        STATS_DATE(t1.object_id, stats_id) < GETDATE()-5 and
        -- не учитываем: мусор, постоянные данные, таблицы на удаление
        t1.name not like 'disable%' and
        object_name(t1.object_id) not like '[__]%' and
        object_name(t1.object_id) not like 'T[_]%' and
        object_name(t1.object_id) not like 'OSMP%' and
        -- исключаем автостатистику,
        -- она создана по ad-hoc запросам, поэтому не является необходимой
        -- во время ночных расчетов
         t1.name not like '[_]WA[_]Sys[_]%'
  order by STATS_DATE(t1.object_id, stats_id);

i/o-нагрузка на файлы

SELECT TOP 10 DB_NAME(saf.dbid) AS [База данных],
       saf.name AS [Логическое имя],
       vfs.BytesRead/1048576 AS [Прочитано (Мб)],
       vfs.BytesWritten/1048576 AS [Записано (Мб)],
       saf.filename AS [Путь к файлу]
  FROM master..sysaltfiles AS saf
  JOIN ::fn_virtualfilestats(NULL,NULL) AS vfs ON vfs.dbid = saf.dbid AND
                                                  vfs.fileid = saf.fileid AND
                                                  saf.dbid NOT IN (1,3,4)
  ORDER BY vfs.BytesRead/1048576 + BytesWritten/1048576 DESC;

i/o-нагрузка на диски

SELECT SUBSTRING(saf.physical_name, 1, 1)    AS [Диск],
       SUM(vfs.num_of_bytes_read/1048576)    AS [Прочитано (Мб)],
       SUM(vfs.num_of_bytes_written/1048576) AS [Записано (Мб)]
  FROM sys.master_files AS saf
  JOIN sys.dm_io_virtual_file_stats(NULL,NULL) AS vfs ON vfs.database_id = saf.database_id AND
                                                         vfs.file_id = saf.file_id AND
                                                         saf.database_id NOT IN (1,3,4) AND
                                                         saf.type < 2
  GROUP BY SUBSTRING(saf.physical_name, 1, 1)
  ORDER BY [Диск];

Занимаемое на диске место

SELECT TOP 1000
       (row_number() over(order by (a1.reserved + ISNULL(a4.reserved,0)) desc))%2 as l1,
       a3.name AS [schemaname],
       a2.name AS [tablename],
       a1.rows as row_count,
      (a1.reserved + ISNULL(a4.reserved,0))* 8 AS reserved,
       a1.data * 8 AS data,
      (CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 AS index_size,
      (CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 AS unused,
      'ALTER TABLE [' + a2.name  + '] REBUILD' as [sql]
  FROM (SELECT ps.object_id,
               SUM(CASE WHEN (ps.index_id < 2) THEN row_count ELSE 0 END) AS [rows],
               SUM(ps.reserved_page_count) AS reserved,
               SUM(CASE WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count) ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count) END) AS data,
               SUM(ps.used_page_count) AS used
          FROM sys.dm_db_partition_stats ps
          GROUP BY ps.object_id
       ) AS a1
  LEFT JOIN (SELECT it.parent_id,
                    SUM(ps.reserved_page_count) AS reserved,
                    SUM(ps.used_page_count) AS used
               FROM sys.dm_db_partition_stats ps
               INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
               WHERE it.internal_type IN (202,204)
               GROUP BY it.parent_id
            ) AS a4 ON (a4.parent_id = a1.object_id)
  INNER JOIN sys.all_objects a2  ON ( a1.object_id = a2.object_id )
  INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)
  WHERE a2.type <> N'S' and a2.type <> N'IT'
  ORDER BY 8 DESC;

под какие объекты выделена память

select count(*)as cached_pages_count,
       obj.name as objectname,
       ind.name as indexname,
       obj.index_id as indexid
  from sys.dm_os_buffer_descriptors as bd
  inner join (select object_id as objectid,
                     object_name(object_id) as name,
                     index_id,allocation_unit_id
                from sys.allocation_units as au
                inner join sys.partitions as p on au.container_id = p.hobt_id and (au.type = 1 or au.type = 3)
                union all
                select object_id as objectid,
                       object_name(object_id) as name,
                       index_id,allocation_unit_id
                  from sys.allocation_units as au
                  inner join sys.partitions as p on au.container_id = p.partition_id and au.type = 2
             ) as obj on bd.allocation_unit_id = obj.allocation_unit_id
  left outer join sys.indexes ind on obj.objectid = ind.object_id and
                                     obj.index_id = ind.index_id
  where bd.database_id = db_id() and
        bd.page_type in ('data_page', 'index_page')
  group by obj.name, ind.name, obj.index_id
  order by cached_pages_count desc;
2013   sql   windows

Windows Vista/7/Server 2008. Не удается загрузить C:\Windows\System32\iprtrmgr.dll

Настраивал маршрутизацию под 2008 r2 сервером и в перед запуском службы получил Windows Vista/7/Server 2008. Не удается загрузить C:\Windows\System32\iprtrmgr.dll.
Необходимо отключить протокол IPv6. В зависимости от ситуации решения разные.

В большинстве случаев для отключения поддержки IPv6 следуем указаниям статьи «Отключение некоторых компонентов протокола IP версии 6 в Windows Vista, Windows 7 и Windows Server 2008» из базы знаний Microsoft. (предпочтительней).

Если ошибка связана с настройкой маршрутизации и удалённого доступа на Windows Server 2008:

Имя журнала:   System
Источник:      RemoteAccess
Дата:          12.09.2011 16:29:53
Код события:   20103
Категория задачи:Отсутствует
Уровень:       Ошибка
Ключевые слова:Классический
Пользователь:  Н/Д
Компьютер:     SERVER.domain.ru
Описание:
Не удается загрузить C:\Windows\System32\iprtrmgr.dll.
Xml события:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="RemoteAccess" />
    <EventID Qualifiers="0">20103</EventID>
    <Level>2</Level>
    <Task>0</Task>
    <Keywords>0x80000000000000</Keywords>
    <TimeCreated SystemTime="2011-09-12T12:29:53.000000000Z" />
    <EventRecordID>10950</EventRecordID>
    <Channel>System</Channel>
    <Computer>SERVER.domain.ru</Computer>
    <Security />
  </System>
  <EventData>
    <Data>C:\Windows\System32\iprtrmgr.dll</Data>
    <Binary>1F000000</Binary>
  </EventData>
</Event>

то следует удалить ветку реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess\RouterManagers\Ipv6:

reg delete "HKLM\SYSTEM\CurrentControlSet\Services\RemoteAccess\RouterManagers\Ipv6" /f

и перезапустить службу «Маршрутизация и удалённый доступ»:

net stop RemoteAccess
net start RemoteAccess
2013   windows
Ранее Ctrl + ↓